]> code.delx.au - gnu-emacs/blob - lisp/emacs-lisp/cl-seq.el
Update copyright notices for 2013.
[gnu-emacs] / lisp / emacs-lisp / cl-seq.el
1 ;;; cl-seq.el --- Common Lisp features, part 3 -*- lexical-binding: t -*-
2
3 ;; Copyright (C) 1993, 2001-2013 Free Software Foundation, Inc.
4
5 ;; Author: Dave Gillespie <daveg@synaptics.com>
6 ;; Version: 2.02
7 ;; Keywords: extensions
8 ;; Package: emacs
9
10 ;; This file is part of GNU Emacs.
11
12 ;; GNU Emacs is free software: you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation, either version 3 of the License, or
15 ;; (at your option) any later version.
16
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
24
25 ;;; Commentary:
26
27 ;; These are extensions to Emacs Lisp that provide a degree of
28 ;; Common Lisp compatibility, beyond what is already built-in
29 ;; in Emacs Lisp.
30 ;;
31 ;; This package was written by Dave Gillespie; it is a complete
32 ;; rewrite of Cesar Quiroz's original cl.el package of December 1986.
33 ;;
34 ;; Bug reports, comments, and suggestions are welcome!
35
36 ;; This file contains the Common Lisp sequence and list functions
37 ;; which take keyword arguments.
38
39 ;; See cl.el for Change Log.
40
41
42 ;;; Code:
43
44 (require 'cl-lib)
45
46 ;; Keyword parsing.
47 ;; This is special-cased here so that we can compile
48 ;; this file independent from cl-macs.
49
50 (defmacro cl--parsing-keywords (kwords other-keys &rest body)
51 (declare (indent 2) (debug (sexp sexp &rest form)))
52 `(let* ,(mapcar
53 (lambda (x)
54 (let* ((var (if (consp x) (car x) x))
55 (mem `(car (cdr (memq ',var cl-keys)))))
56 (if (eq var :test-not)
57 (setq mem `(and ,mem (setq cl-test ,mem) t)))
58 (if (eq var :if-not)
59 (setq mem `(and ,mem (setq cl-if ,mem) t)))
60 (list (intern
61 (format "cl-%s" (substring (symbol-name var) 1)))
62 (if (consp x) `(or ,mem ,(car (cdr x))) mem))))
63 kwords)
64 ,@(append
65 (and (not (eq other-keys t))
66 (list
67 (list 'let '((cl-keys-temp cl-keys))
68 (list 'while 'cl-keys-temp
69 (list 'or (list 'memq '(car cl-keys-temp)
70 (list 'quote
71 (mapcar
72 (function
73 (lambda (x)
74 (if (consp x)
75 (car x) x)))
76 (append kwords
77 other-keys))))
78 '(car (cdr (memq (quote :allow-other-keys)
79 cl-keys)))
80 '(error "Bad keyword argument %s"
81 (car cl-keys-temp)))
82 '(setq cl-keys-temp (cdr (cdr cl-keys-temp)))))))
83 body)))
84
85 (defmacro cl--check-key (x) ;Expects `cl-key' in context of generated code.
86 (declare (debug edebug-forms))
87 `(if cl-key (funcall cl-key ,x) ,x))
88
89 (defmacro cl--check-test-nokey (item x) ;cl-test cl-if cl-test-not cl-if-not.
90 (declare (debug edebug-forms))
91 `(cond
92 (cl-test (eq (not (funcall cl-test ,item ,x))
93 cl-test-not))
94 (cl-if (eq (not (funcall cl-if ,x)) cl-if-not))
95 (t (eql ,item ,x))))
96
97 (defmacro cl--check-test (item x) ;all of the above.
98 (declare (debug edebug-forms))
99 `(cl--check-test-nokey ,item (cl--check-key ,x)))
100
101 (defmacro cl--check-match (x y) ;cl-key cl-test cl-test-not
102 (declare (debug edebug-forms))
103 (setq x `(cl--check-key ,x) y `(cl--check-key ,y))
104 `(if cl-test
105 (eq (not (funcall cl-test ,x ,y)) cl-test-not)
106 (eql ,x ,y)))
107
108 (defvar cl-test) (defvar cl-test-not)
109 (defvar cl-if) (defvar cl-if-not)
110 (defvar cl-key)
111
112 ;;;###autoload
113 (defun cl-reduce (cl-func cl-seq &rest cl-keys)
114 "Reduce two-argument FUNCTION across SEQ.
115 \nKeywords supported: :start :end :from-end :initial-value :key
116 \n(fn FUNCTION SEQ [KEYWORD VALUE]...)"
117 (cl--parsing-keywords (:from-end (:start 0) :end :initial-value :key) ()
118 (or (listp cl-seq) (setq cl-seq (append cl-seq nil)))
119 (setq cl-seq (cl-subseq cl-seq cl-start cl-end))
120 (if cl-from-end (setq cl-seq (nreverse cl-seq)))
121 (let ((cl-accum (cond ((memq :initial-value cl-keys) cl-initial-value)
122 (cl-seq (cl--check-key (pop cl-seq)))
123 (t (funcall cl-func)))))
124 (if cl-from-end
125 (while cl-seq
126 (setq cl-accum (funcall cl-func (cl--check-key (pop cl-seq))
127 cl-accum)))
128 (while cl-seq
129 (setq cl-accum (funcall cl-func cl-accum
130 (cl--check-key (pop cl-seq))))))
131 cl-accum)))
132
133 ;;;###autoload
134 (defun cl-fill (seq item &rest cl-keys)
135 "Fill the elements of SEQ with ITEM.
136 \nKeywords supported: :start :end
137 \n(fn SEQ ITEM [KEYWORD VALUE]...)"
138 (cl--parsing-keywords ((:start 0) :end) ()
139 (if (listp seq)
140 (let ((p (nthcdr cl-start seq))
141 (n (if cl-end (- cl-end cl-start) 8000000)))
142 (while (and p (>= (setq n (1- n)) 0))
143 (setcar p item)
144 (setq p (cdr p))))
145 (or cl-end (setq cl-end (length seq)))
146 (if (and (= cl-start 0) (= cl-end (length seq)))
147 (fillarray seq item)
148 (while (< cl-start cl-end)
149 (aset seq cl-start item)
150 (setq cl-start (1+ cl-start)))))
151 seq))
152
153 ;;;###autoload
154 (defun cl-replace (cl-seq1 cl-seq2 &rest cl-keys)
155 "Replace the elements of SEQ1 with the elements of SEQ2.
156 SEQ1 is destructively modified, then returned.
157 \nKeywords supported: :start1 :end1 :start2 :end2
158 \n(fn SEQ1 SEQ2 [KEYWORD VALUE]...)"
159 (cl--parsing-keywords ((:start1 0) :end1 (:start2 0) :end2) ()
160 (if (and (eq cl-seq1 cl-seq2) (<= cl-start2 cl-start1))
161 (or (= cl-start1 cl-start2)
162 (let* ((cl-len (length cl-seq1))
163 (cl-n (min (- (or cl-end1 cl-len) cl-start1)
164 (- (or cl-end2 cl-len) cl-start2))))
165 (while (>= (setq cl-n (1- cl-n)) 0)
166 (cl--set-elt cl-seq1 (+ cl-start1 cl-n)
167 (elt cl-seq2 (+ cl-start2 cl-n))))))
168 (if (listp cl-seq1)
169 (let ((cl-p1 (nthcdr cl-start1 cl-seq1))
170 (cl-n1 (if cl-end1 (- cl-end1 cl-start1) 4000000)))
171 (if (listp cl-seq2)
172 (let ((cl-p2 (nthcdr cl-start2 cl-seq2))
173 (cl-n (min cl-n1
174 (if cl-end2 (- cl-end2 cl-start2) 4000000))))
175 (while (and cl-p1 cl-p2 (>= (setq cl-n (1- cl-n)) 0))
176 (setcar cl-p1 (car cl-p2))
177 (setq cl-p1 (cdr cl-p1) cl-p2 (cdr cl-p2))))
178 (setq cl-end2 (min (or cl-end2 (length cl-seq2))
179 (+ cl-start2 cl-n1)))
180 (while (and cl-p1 (< cl-start2 cl-end2))
181 (setcar cl-p1 (aref cl-seq2 cl-start2))
182 (setq cl-p1 (cdr cl-p1) cl-start2 (1+ cl-start2)))))
183 (setq cl-end1 (min (or cl-end1 (length cl-seq1))
184 (+ cl-start1 (- (or cl-end2 (length cl-seq2))
185 cl-start2))))
186 (if (listp cl-seq2)
187 (let ((cl-p2 (nthcdr cl-start2 cl-seq2)))
188 (while (< cl-start1 cl-end1)
189 (aset cl-seq1 cl-start1 (car cl-p2))
190 (setq cl-p2 (cdr cl-p2) cl-start1 (1+ cl-start1))))
191 (while (< cl-start1 cl-end1)
192 (aset cl-seq1 cl-start1 (aref cl-seq2 cl-start2))
193 (setq cl-start2 (1+ cl-start2) cl-start1 (1+ cl-start1))))))
194 cl-seq1))
195
196 ;;;###autoload
197 (defun cl-remove (cl-item cl-seq &rest cl-keys)
198 "Remove all occurrences of ITEM in SEQ.
199 This is a non-destructive function; it makes a copy of SEQ if necessary
200 to avoid corrupting the original SEQ.
201 \nKeywords supported: :test :test-not :key :count :start :end :from-end
202 \n(fn ITEM SEQ [KEYWORD VALUE]...)"
203 (cl--parsing-keywords (:test :test-not :key :if :if-not :count :from-end
204 (:start 0) :end) ()
205 (if (<= (or cl-count (setq cl-count 8000000)) 0)
206 cl-seq
207 (if (or (nlistp cl-seq) (and cl-from-end (< cl-count 4000000)))
208 (let ((cl-i (cl--position cl-item cl-seq cl-start cl-end
209 cl-from-end)))
210 (if cl-i
211 (let ((cl-res (apply 'cl-delete cl-item (append cl-seq nil)
212 (append (if cl-from-end
213 (list :end (1+ cl-i))
214 (list :start cl-i))
215 cl-keys))))
216 (if (listp cl-seq) cl-res
217 (if (stringp cl-seq) (concat cl-res) (vconcat cl-res))))
218 cl-seq))
219 (setq cl-end (- (or cl-end 8000000) cl-start))
220 (if (= cl-start 0)
221 (while (and cl-seq (> cl-end 0)
222 (cl--check-test cl-item (car cl-seq))
223 (setq cl-end (1- cl-end) cl-seq (cdr cl-seq))
224 (> (setq cl-count (1- cl-count)) 0))))
225 (if (and (> cl-count 0) (> cl-end 0))
226 (let ((cl-p (if (> cl-start 0) (nthcdr cl-start cl-seq)
227 (setq cl-end (1- cl-end)) (cdr cl-seq))))
228 (while (and cl-p (> cl-end 0)
229 (not (cl--check-test cl-item (car cl-p))))
230 (setq cl-p (cdr cl-p) cl-end (1- cl-end)))
231 (if (and cl-p (> cl-end 0))
232 (nconc (cl-ldiff cl-seq cl-p)
233 (if (= cl-count 1) (cdr cl-p)
234 (and (cdr cl-p)
235 (apply 'cl-delete cl-item
236 (copy-sequence (cdr cl-p))
237 :start 0 :end (1- cl-end)
238 :count (1- cl-count) cl-keys))))
239 cl-seq))
240 cl-seq)))))
241
242 ;;;###autoload
243 (defun cl-remove-if (cl-pred cl-list &rest cl-keys)
244 "Remove all items satisfying PREDICATE in SEQ.
245 This is a non-destructive function; it makes a copy of SEQ if necessary
246 to avoid corrupting the original SEQ.
247 \nKeywords supported: :key :count :start :end :from-end
248 \n(fn PREDICATE SEQ [KEYWORD VALUE]...)"
249 (apply 'cl-remove nil cl-list :if cl-pred cl-keys))
250
251 ;;;###autoload
252 (defun cl-remove-if-not (cl-pred cl-list &rest cl-keys)
253 "Remove all items not satisfying PREDICATE in SEQ.
254 This is a non-destructive function; it makes a copy of SEQ if necessary
255 to avoid corrupting the original SEQ.
256 \nKeywords supported: :key :count :start :end :from-end
257 \n(fn PREDICATE SEQ [KEYWORD VALUE]...)"
258 (apply 'cl-remove nil cl-list :if-not cl-pred cl-keys))
259
260 ;;;###autoload
261 (defun cl-delete (cl-item cl-seq &rest cl-keys)
262 "Remove all occurrences of ITEM in SEQ.
263 This is a destructive function; it reuses the storage of SEQ whenever possible.
264 \nKeywords supported: :test :test-not :key :count :start :end :from-end
265 \n(fn ITEM SEQ [KEYWORD VALUE]...)"
266 (cl--parsing-keywords (:test :test-not :key :if :if-not :count :from-end
267 (:start 0) :end) ()
268 (if (<= (or cl-count (setq cl-count 8000000)) 0)
269 cl-seq
270 (if (listp cl-seq)
271 (if (and cl-from-end (< cl-count 4000000))
272 (let (cl-i)
273 (while (and (>= (setq cl-count (1- cl-count)) 0)
274 (setq cl-i (cl--position cl-item cl-seq cl-start
275 cl-end cl-from-end)))
276 (if (= cl-i 0) (setq cl-seq (cdr cl-seq))
277 (let ((cl-tail (nthcdr (1- cl-i) cl-seq)))
278 (setcdr cl-tail (cdr (cdr cl-tail)))))
279 (setq cl-end cl-i))
280 cl-seq)
281 (setq cl-end (- (or cl-end 8000000) cl-start))
282 (if (= cl-start 0)
283 (progn
284 (while (and cl-seq
285 (> cl-end 0)
286 (cl--check-test cl-item (car cl-seq))
287 (setq cl-end (1- cl-end) cl-seq (cdr cl-seq))
288 (> (setq cl-count (1- cl-count)) 0)))
289 (setq cl-end (1- cl-end)))
290 (setq cl-start (1- cl-start)))
291 (if (and (> cl-count 0) (> cl-end 0))
292 (let ((cl-p (nthcdr cl-start cl-seq)))
293 (while (and (cdr cl-p) (> cl-end 0))
294 (if (cl--check-test cl-item (car (cdr cl-p)))
295 (progn
296 (setcdr cl-p (cdr (cdr cl-p)))
297 (if (= (setq cl-count (1- cl-count)) 0)
298 (setq cl-end 1)))
299 (setq cl-p (cdr cl-p)))
300 (setq cl-end (1- cl-end)))))
301 cl-seq)
302 (apply 'cl-remove cl-item cl-seq cl-keys)))))
303
304 ;;;###autoload
305 (defun cl-delete-if (cl-pred cl-list &rest cl-keys)
306 "Remove all items satisfying PREDICATE in SEQ.
307 This is a destructive function; it reuses the storage of SEQ whenever possible.
308 \nKeywords supported: :key :count :start :end :from-end
309 \n(fn PREDICATE SEQ [KEYWORD VALUE]...)"
310 (apply 'cl-delete nil cl-list :if cl-pred cl-keys))
311
312 ;;;###autoload
313 (defun cl-delete-if-not (cl-pred cl-list &rest cl-keys)
314 "Remove all items not satisfying PREDICATE in SEQ.
315 This is a destructive function; it reuses the storage of SEQ whenever possible.
316 \nKeywords supported: :key :count :start :end :from-end
317 \n(fn PREDICATE SEQ [KEYWORD VALUE]...)"
318 (apply 'cl-delete nil cl-list :if-not cl-pred cl-keys))
319
320 ;;;###autoload
321 (defun cl-remove-duplicates (cl-seq &rest cl-keys)
322 "Return a copy of SEQ with all duplicate elements removed.
323 \nKeywords supported: :test :test-not :key :start :end :from-end
324 \n(fn SEQ [KEYWORD VALUE]...)"
325 (cl--delete-duplicates cl-seq cl-keys t))
326
327 ;;;###autoload
328 (defun cl-delete-duplicates (cl-seq &rest cl-keys)
329 "Remove all duplicate elements from SEQ (destructively).
330 \nKeywords supported: :test :test-not :key :start :end :from-end
331 \n(fn SEQ [KEYWORD VALUE]...)"
332 (cl--delete-duplicates cl-seq cl-keys nil))
333
334 (defun cl--delete-duplicates (cl-seq cl-keys cl-copy)
335 (if (listp cl-seq)
336 (cl--parsing-keywords (:test :test-not :key (:start 0) :end :from-end :if)
337 ()
338 (if cl-from-end
339 (let ((cl-p (nthcdr cl-start cl-seq)) cl-i)
340 (setq cl-end (- (or cl-end (length cl-seq)) cl-start))
341 (while (> cl-end 1)
342 (setq cl-i 0)
343 (while (setq cl-i (cl--position (cl--check-key (car cl-p))
344 (cdr cl-p) cl-i (1- cl-end)))
345 (if cl-copy (setq cl-seq (copy-sequence cl-seq)
346 cl-p (nthcdr cl-start cl-seq) cl-copy nil))
347 (let ((cl-tail (nthcdr cl-i cl-p)))
348 (setcdr cl-tail (cdr (cdr cl-tail))))
349 (setq cl-end (1- cl-end)))
350 (setq cl-p (cdr cl-p) cl-end (1- cl-end)
351 cl-start (1+ cl-start)))
352 cl-seq)
353 (setq cl-end (- (or cl-end (length cl-seq)) cl-start))
354 (while (and (cdr cl-seq) (= cl-start 0) (> cl-end 1)
355 (cl--position (cl--check-key (car cl-seq))
356 (cdr cl-seq) 0 (1- cl-end)))
357 (setq cl-seq (cdr cl-seq) cl-end (1- cl-end)))
358 (let ((cl-p (if (> cl-start 0) (nthcdr (1- cl-start) cl-seq)
359 (setq cl-end (1- cl-end) cl-start 1) cl-seq)))
360 (while (and (cdr (cdr cl-p)) (> cl-end 1))
361 (if (cl--position (cl--check-key (car (cdr cl-p)))
362 (cdr (cdr cl-p)) 0 (1- cl-end))
363 (progn
364 (if cl-copy (setq cl-seq (copy-sequence cl-seq)
365 cl-p (nthcdr (1- cl-start) cl-seq)
366 cl-copy nil))
367 (setcdr cl-p (cdr (cdr cl-p))))
368 (setq cl-p (cdr cl-p)))
369 (setq cl-end (1- cl-end) cl-start (1+ cl-start)))
370 cl-seq)))
371 (let ((cl-res (cl--delete-duplicates (append cl-seq nil) cl-keys nil)))
372 (if (stringp cl-seq) (concat cl-res) (vconcat cl-res)))))
373
374 ;;;###autoload
375 (defun cl-substitute (cl-new cl-old cl-seq &rest cl-keys)
376 "Substitute NEW for OLD in SEQ.
377 This is a non-destructive function; it makes a copy of SEQ if necessary
378 to avoid corrupting the original SEQ.
379 \nKeywords supported: :test :test-not :key :count :start :end :from-end
380 \n(fn NEW OLD SEQ [KEYWORD VALUE]...)"
381 (cl--parsing-keywords (:test :test-not :key :if :if-not :count
382 (:start 0) :end :from-end) ()
383 (if (or (eq cl-old cl-new)
384 (<= (or cl-count (setq cl-from-end nil cl-count 8000000)) 0))
385 cl-seq
386 (let ((cl-i (cl--position cl-old cl-seq cl-start cl-end)))
387 (if (not cl-i)
388 cl-seq
389 (setq cl-seq (copy-sequence cl-seq))
390 (or cl-from-end
391 (progn (cl--set-elt cl-seq cl-i cl-new)
392 (setq cl-i (1+ cl-i) cl-count (1- cl-count))))
393 (apply 'cl-nsubstitute cl-new cl-old cl-seq :count cl-count
394 :start cl-i cl-keys))))))
395
396 ;;;###autoload
397 (defun cl-substitute-if (cl-new cl-pred cl-list &rest cl-keys)
398 "Substitute NEW for all items satisfying PREDICATE in SEQ.
399 This is a non-destructive function; it makes a copy of SEQ if necessary
400 to avoid corrupting the original SEQ.
401 \nKeywords supported: :key :count :start :end :from-end
402 \n(fn NEW PREDICATE SEQ [KEYWORD VALUE]...)"
403 (apply 'cl-substitute cl-new nil cl-list :if cl-pred cl-keys))
404
405 ;;;###autoload
406 (defun cl-substitute-if-not (cl-new cl-pred cl-list &rest cl-keys)
407 "Substitute NEW for all items not satisfying PREDICATE in SEQ.
408 This is a non-destructive function; it makes a copy of SEQ if necessary
409 to avoid corrupting the original SEQ.
410 \nKeywords supported: :key :count :start :end :from-end
411 \n(fn NEW PREDICATE SEQ [KEYWORD VALUE]...)"
412 (apply 'cl-substitute cl-new nil cl-list :if-not cl-pred cl-keys))
413
414 ;;;###autoload
415 (defun cl-nsubstitute (cl-new cl-old cl-seq &rest cl-keys)
416 "Substitute NEW for OLD in SEQ.
417 This is a destructive function; it reuses the storage of SEQ whenever possible.
418 \nKeywords supported: :test :test-not :key :count :start :end :from-end
419 \n(fn NEW OLD SEQ [KEYWORD VALUE]...)"
420 (cl--parsing-keywords (:test :test-not :key :if :if-not :count
421 (:start 0) :end :from-end) ()
422 (or (eq cl-old cl-new) (<= (or cl-count (setq cl-count 8000000)) 0)
423 (if (and (listp cl-seq) (or (not cl-from-end) (> cl-count 4000000)))
424 (let ((cl-p (nthcdr cl-start cl-seq)))
425 (setq cl-end (- (or cl-end 8000000) cl-start))
426 (while (and cl-p (> cl-end 0) (> cl-count 0))
427 (if (cl--check-test cl-old (car cl-p))
428 (progn
429 (setcar cl-p cl-new)
430 (setq cl-count (1- cl-count))))
431 (setq cl-p (cdr cl-p) cl-end (1- cl-end))))
432 (or cl-end (setq cl-end (length cl-seq)))
433 (if cl-from-end
434 (while (and (< cl-start cl-end) (> cl-count 0))
435 (setq cl-end (1- cl-end))
436 (if (cl--check-test cl-old (elt cl-seq cl-end))
437 (progn
438 (cl--set-elt cl-seq cl-end cl-new)
439 (setq cl-count (1- cl-count)))))
440 (while (and (< cl-start cl-end) (> cl-count 0))
441 (if (cl--check-test cl-old (aref cl-seq cl-start))
442 (progn
443 (aset cl-seq cl-start cl-new)
444 (setq cl-count (1- cl-count))))
445 (setq cl-start (1+ cl-start))))))
446 cl-seq))
447
448 ;;;###autoload
449 (defun cl-nsubstitute-if (cl-new cl-pred cl-list &rest cl-keys)
450 "Substitute NEW for all items satisfying PREDICATE in SEQ.
451 This is a destructive function; it reuses the storage of SEQ whenever possible.
452 \nKeywords supported: :key :count :start :end :from-end
453 \n(fn NEW PREDICATE SEQ [KEYWORD VALUE]...)"
454 (apply 'cl-nsubstitute cl-new nil cl-list :if cl-pred cl-keys))
455
456 ;;;###autoload
457 (defun cl-nsubstitute-if-not (cl-new cl-pred cl-list &rest cl-keys)
458 "Substitute NEW for all items not satisfying PREDICATE in SEQ.
459 This is a destructive function; it reuses the storage of SEQ whenever possible.
460 \nKeywords supported: :key :count :start :end :from-end
461 \n(fn NEW PREDICATE SEQ [KEYWORD VALUE]...)"
462 (apply 'cl-nsubstitute cl-new nil cl-list :if-not cl-pred cl-keys))
463
464 ;;;###autoload
465 (defun cl-find (cl-item cl-seq &rest cl-keys)
466 "Find the first occurrence of ITEM in SEQ.
467 Return the matching ITEM, or nil if not found.
468 \nKeywords supported: :test :test-not :key :start :end :from-end
469 \n(fn ITEM SEQ [KEYWORD VALUE]...)"
470 (let ((cl-pos (apply 'cl-position cl-item cl-seq cl-keys)))
471 (and cl-pos (elt cl-seq cl-pos))))
472
473 ;;;###autoload
474 (defun cl-find-if (cl-pred cl-list &rest cl-keys)
475 "Find the first item satisfying PREDICATE in SEQ.
476 Return the matching item, or nil if not found.
477 \nKeywords supported: :key :start :end :from-end
478 \n(fn PREDICATE SEQ [KEYWORD VALUE]...)"
479 (apply 'cl-find nil cl-list :if cl-pred cl-keys))
480
481 ;;;###autoload
482 (defun cl-find-if-not (cl-pred cl-list &rest cl-keys)
483 "Find the first item not satisfying PREDICATE in SEQ.
484 Return the matching item, or nil if not found.
485 \nKeywords supported: :key :start :end :from-end
486 \n(fn PREDICATE SEQ [KEYWORD VALUE]...)"
487 (apply 'cl-find nil cl-list :if-not cl-pred cl-keys))
488
489 ;;;###autoload
490 (defun cl-position (cl-item cl-seq &rest cl-keys)
491 "Find the first occurrence of ITEM in SEQ.
492 Return the index of the matching item, or nil if not found.
493 \nKeywords supported: :test :test-not :key :start :end :from-end
494 \n(fn ITEM SEQ [KEYWORD VALUE]...)"
495 (cl--parsing-keywords (:test :test-not :key :if :if-not
496 (:start 0) :end :from-end) ()
497 (cl--position cl-item cl-seq cl-start cl-end cl-from-end)))
498
499 (defun cl--position (cl-item cl-seq cl-start &optional cl-end cl-from-end)
500 (if (listp cl-seq)
501 (let ((cl-p (nthcdr cl-start cl-seq)))
502 (or cl-end (setq cl-end 8000000))
503 (let ((cl-res nil))
504 (while (and cl-p (< cl-start cl-end) (or (not cl-res) cl-from-end))
505 (if (cl--check-test cl-item (car cl-p))
506 (setq cl-res cl-start))
507 (setq cl-p (cdr cl-p) cl-start (1+ cl-start)))
508 cl-res))
509 (or cl-end (setq cl-end (length cl-seq)))
510 (if cl-from-end
511 (progn
512 (while (and (>= (setq cl-end (1- cl-end)) cl-start)
513 (not (cl--check-test cl-item (aref cl-seq cl-end)))))
514 (and (>= cl-end cl-start) cl-end))
515 (while (and (< cl-start cl-end)
516 (not (cl--check-test cl-item (aref cl-seq cl-start))))
517 (setq cl-start (1+ cl-start)))
518 (and (< cl-start cl-end) cl-start))))
519
520 ;;;###autoload
521 (defun cl-position-if (cl-pred cl-list &rest cl-keys)
522 "Find the first item satisfying PREDICATE in SEQ.
523 Return the index of the matching item, or nil if not found.
524 \nKeywords supported: :key :start :end :from-end
525 \n(fn PREDICATE SEQ [KEYWORD VALUE]...)"
526 (apply 'cl-position nil cl-list :if cl-pred cl-keys))
527
528 ;;;###autoload
529 (defun cl-position-if-not (cl-pred cl-list &rest cl-keys)
530 "Find the first item not satisfying PREDICATE in SEQ.
531 Return the index of the matching item, or nil if not found.
532 \nKeywords supported: :key :start :end :from-end
533 \n(fn PREDICATE SEQ [KEYWORD VALUE]...)"
534 (apply 'cl-position nil cl-list :if-not cl-pred cl-keys))
535
536 ;;;###autoload
537 (defun cl-count (cl-item cl-seq &rest cl-keys)
538 "Count the number of occurrences of ITEM in SEQ.
539 \nKeywords supported: :test :test-not :key :start :end
540 \n(fn ITEM SEQ [KEYWORD VALUE]...)"
541 (cl--parsing-keywords (:test :test-not :key :if :if-not (:start 0) :end) ()
542 (let ((cl-count 0) cl-x)
543 (or cl-end (setq cl-end (length cl-seq)))
544 (if (consp cl-seq) (setq cl-seq (nthcdr cl-start cl-seq)))
545 (while (< cl-start cl-end)
546 (setq cl-x (if (consp cl-seq) (pop cl-seq) (aref cl-seq cl-start)))
547 (if (cl--check-test cl-item cl-x) (setq cl-count (1+ cl-count)))
548 (setq cl-start (1+ cl-start)))
549 cl-count)))
550
551 ;;;###autoload
552 (defun cl-count-if (cl-pred cl-list &rest cl-keys)
553 "Count the number of items satisfying PREDICATE in SEQ.
554 \nKeywords supported: :key :start :end
555 \n(fn PREDICATE SEQ [KEYWORD VALUE]...)"
556 (apply 'cl-count nil cl-list :if cl-pred cl-keys))
557
558 ;;;###autoload
559 (defun cl-count-if-not (cl-pred cl-list &rest cl-keys)
560 "Count the number of items not satisfying PREDICATE in SEQ.
561 \nKeywords supported: :key :start :end
562 \n(fn PREDICATE SEQ [KEYWORD VALUE]...)"
563 (apply 'cl-count nil cl-list :if-not cl-pred cl-keys))
564
565 ;;;###autoload
566 (defun cl-mismatch (cl-seq1 cl-seq2 &rest cl-keys)
567 "Compare SEQ1 with SEQ2, return index of first mismatching element.
568 Return nil if the sequences match. If one sequence is a prefix of the
569 other, the return value indicates the end of the shorter sequence.
570 \nKeywords supported: :test :test-not :key :start1 :end1 :start2 :end2 :from-end
571 \n(fn SEQ1 SEQ2 [KEYWORD VALUE]...)"
572 (cl--parsing-keywords (:test :test-not :key :from-end
573 (:start1 0) :end1 (:start2 0) :end2) ()
574 (or cl-end1 (setq cl-end1 (length cl-seq1)))
575 (or cl-end2 (setq cl-end2 (length cl-seq2)))
576 (if cl-from-end
577 (progn
578 (while (and (< cl-start1 cl-end1) (< cl-start2 cl-end2)
579 (cl--check-match (elt cl-seq1 (1- cl-end1))
580 (elt cl-seq2 (1- cl-end2))))
581 (setq cl-end1 (1- cl-end1) cl-end2 (1- cl-end2)))
582 (and (or (< cl-start1 cl-end1) (< cl-start2 cl-end2))
583 (1- cl-end1)))
584 (let ((cl-p1 (and (listp cl-seq1) (nthcdr cl-start1 cl-seq1)))
585 (cl-p2 (and (listp cl-seq2) (nthcdr cl-start2 cl-seq2))))
586 (while (and (< cl-start1 cl-end1) (< cl-start2 cl-end2)
587 (cl--check-match (if cl-p1 (car cl-p1)
588 (aref cl-seq1 cl-start1))
589 (if cl-p2 (car cl-p2)
590 (aref cl-seq2 cl-start2))))
591 (setq cl-p1 (cdr cl-p1) cl-p2 (cdr cl-p2)
592 cl-start1 (1+ cl-start1) cl-start2 (1+ cl-start2)))
593 (and (or (< cl-start1 cl-end1) (< cl-start2 cl-end2))
594 cl-start1)))))
595
596 ;;;###autoload
597 (defun cl-search (cl-seq1 cl-seq2 &rest cl-keys)
598 "Search for SEQ1 as a subsequence of SEQ2.
599 Return the index of the leftmost element of the first match found;
600 return nil if there are no matches.
601 \nKeywords supported: :test :test-not :key :start1 :end1 :start2 :end2 :from-end
602 \n(fn SEQ1 SEQ2 [KEYWORD VALUE]...)"
603 (cl--parsing-keywords (:test :test-not :key :from-end
604 (:start1 0) :end1 (:start2 0) :end2) ()
605 (or cl-end1 (setq cl-end1 (length cl-seq1)))
606 (or cl-end2 (setq cl-end2 (length cl-seq2)))
607 (if (>= cl-start1 cl-end1)
608 (if cl-from-end cl-end2 cl-start2)
609 (let* ((cl-len (- cl-end1 cl-start1))
610 (cl-first (cl--check-key (elt cl-seq1 cl-start1)))
611 (cl-if nil) cl-pos)
612 (setq cl-end2 (- cl-end2 (1- cl-len)))
613 (while (and (< cl-start2 cl-end2)
614 (setq cl-pos (cl--position cl-first cl-seq2
615 cl-start2 cl-end2 cl-from-end))
616 (apply 'cl-mismatch cl-seq1 cl-seq2
617 :start1 (1+ cl-start1) :end1 cl-end1
618 :start2 (1+ cl-pos) :end2 (+ cl-pos cl-len)
619 :from-end nil cl-keys))
620 (if cl-from-end (setq cl-end2 cl-pos) (setq cl-start2 (1+ cl-pos))))
621 (and (< cl-start2 cl-end2) cl-pos)))))
622
623 ;;;###autoload
624 (defun cl-sort (cl-seq cl-pred &rest cl-keys)
625 "Sort the argument SEQ according to PREDICATE.
626 This is a destructive function; it reuses the storage of SEQ if possible.
627 \nKeywords supported: :key
628 \n(fn SEQ PREDICATE [KEYWORD VALUE]...)"
629 (if (nlistp cl-seq)
630 (cl-replace cl-seq (apply 'cl-sort (append cl-seq nil) cl-pred cl-keys))
631 (cl--parsing-keywords (:key) ()
632 (if (memq cl-key '(nil identity))
633 (sort cl-seq cl-pred)
634 (sort cl-seq (function (lambda (cl-x cl-y)
635 (funcall cl-pred (funcall cl-key cl-x)
636 (funcall cl-key cl-y)))))))))
637
638 ;;;###autoload
639 (defun cl-stable-sort (cl-seq cl-pred &rest cl-keys)
640 "Sort the argument SEQ stably according to PREDICATE.
641 This is a destructive function; it reuses the storage of SEQ if possible.
642 \nKeywords supported: :key
643 \n(fn SEQ PREDICATE [KEYWORD VALUE]...)"
644 (apply 'cl-sort cl-seq cl-pred cl-keys))
645
646 ;;;###autoload
647 (defun cl-merge (cl-type cl-seq1 cl-seq2 cl-pred &rest cl-keys)
648 "Destructively merge the two sequences to produce a new sequence.
649 TYPE is the sequence type to return, SEQ1 and SEQ2 are the two argument
650 sequences, and PREDICATE is a `less-than' predicate on the elements.
651 \nKeywords supported: :key
652 \n(fn TYPE SEQ1 SEQ2 PREDICATE [KEYWORD VALUE]...)"
653 (or (listp cl-seq1) (setq cl-seq1 (append cl-seq1 nil)))
654 (or (listp cl-seq2) (setq cl-seq2 (append cl-seq2 nil)))
655 (cl--parsing-keywords (:key) ()
656 (let ((cl-res nil))
657 (while (and cl-seq1 cl-seq2)
658 (if (funcall cl-pred (cl--check-key (car cl-seq2))
659 (cl--check-key (car cl-seq1)))
660 (push (pop cl-seq2) cl-res)
661 (push (pop cl-seq1) cl-res)))
662 (cl-coerce (nconc (nreverse cl-res) cl-seq1 cl-seq2) cl-type))))
663
664 ;;;###autoload
665 (defun cl-member (cl-item cl-list &rest cl-keys)
666 "Find the first occurrence of ITEM in LIST.
667 Return the sublist of LIST whose car is ITEM.
668 \nKeywords supported: :test :test-not :key
669 \n(fn ITEM LIST [KEYWORD VALUE]...)"
670 (declare (compiler-macro cl--compiler-macro-member))
671 (if cl-keys
672 (cl--parsing-keywords (:test :test-not :key :if :if-not) ()
673 (while (and cl-list (not (cl--check-test cl-item (car cl-list))))
674 (setq cl-list (cdr cl-list)))
675 cl-list)
676 (if (and (numberp cl-item) (not (integerp cl-item)))
677 (member cl-item cl-list)
678 (memq cl-item cl-list))))
679 (autoload 'cl--compiler-macro-member "cl-macs")
680
681 ;;;###autoload
682 (defun cl-member-if (cl-pred cl-list &rest cl-keys)
683 "Find the first item satisfying PREDICATE in LIST.
684 Return the sublist of LIST whose car matches.
685 \nKeywords supported: :key
686 \n(fn PREDICATE LIST [KEYWORD VALUE]...)"
687 (apply 'cl-member nil cl-list :if cl-pred cl-keys))
688
689 ;;;###autoload
690 (defun cl-member-if-not (cl-pred cl-list &rest cl-keys)
691 "Find the first item not satisfying PREDICATE in LIST.
692 Return the sublist of LIST whose car matches.
693 \nKeywords supported: :key
694 \n(fn PREDICATE LIST [KEYWORD VALUE]...)"
695 (apply 'cl-member nil cl-list :if-not cl-pred cl-keys))
696
697 ;;;###autoload
698 (defun cl--adjoin (cl-item cl-list &rest cl-keys)
699 (if (cl--parsing-keywords (:key) t
700 (apply 'cl-member (cl--check-key cl-item) cl-list cl-keys))
701 cl-list
702 (cons cl-item cl-list)))
703
704 ;;;###autoload
705 (defun cl-assoc (cl-item cl-alist &rest cl-keys)
706 "Find the first item whose car matches ITEM in LIST.
707 \nKeywords supported: :test :test-not :key
708 \n(fn ITEM LIST [KEYWORD VALUE]...)"
709 (declare (compiler-macro cl--compiler-macro-assoc))
710 (if cl-keys
711 (cl--parsing-keywords (:test :test-not :key :if :if-not) ()
712 (while (and cl-alist
713 (or (not (consp (car cl-alist)))
714 (not (cl--check-test cl-item (car (car cl-alist))))))
715 (setq cl-alist (cdr cl-alist)))
716 (and cl-alist (car cl-alist)))
717 (if (and (numberp cl-item) (not (integerp cl-item)))
718 (assoc cl-item cl-alist)
719 (assq cl-item cl-alist))))
720 (autoload 'cl--compiler-macro-assoc "cl-macs")
721
722 ;;;###autoload
723 (defun cl-assoc-if (cl-pred cl-list &rest cl-keys)
724 "Find the first item whose car satisfies PREDICATE in LIST.
725 \nKeywords supported: :key
726 \n(fn PREDICATE LIST [KEYWORD VALUE]...)"
727 (apply 'cl-assoc nil cl-list :if cl-pred cl-keys))
728
729 ;;;###autoload
730 (defun cl-assoc-if-not (cl-pred cl-list &rest cl-keys)
731 "Find the first item whose car does not satisfy PREDICATE in LIST.
732 \nKeywords supported: :key
733 \n(fn PREDICATE LIST [KEYWORD VALUE]...)"
734 (apply 'cl-assoc nil cl-list :if-not cl-pred cl-keys))
735
736 ;;;###autoload
737 (defun cl-rassoc (cl-item cl-alist &rest cl-keys)
738 "Find the first item whose cdr matches ITEM in LIST.
739 \nKeywords supported: :test :test-not :key
740 \n(fn ITEM LIST [KEYWORD VALUE]...)"
741 (if (or cl-keys (numberp cl-item))
742 (cl--parsing-keywords (:test :test-not :key :if :if-not) ()
743 (while (and cl-alist
744 (or (not (consp (car cl-alist)))
745 (not (cl--check-test cl-item (cdr (car cl-alist))))))
746 (setq cl-alist (cdr cl-alist)))
747 (and cl-alist (car cl-alist)))
748 (rassq cl-item cl-alist)))
749
750 ;;;###autoload
751 (defun cl-rassoc-if (cl-pred cl-list &rest cl-keys)
752 "Find the first item whose cdr satisfies PREDICATE in LIST.
753 \nKeywords supported: :key
754 \n(fn PREDICATE LIST [KEYWORD VALUE]...)"
755 (apply 'cl-rassoc nil cl-list :if cl-pred cl-keys))
756
757 ;;;###autoload
758 (defun cl-rassoc-if-not (cl-pred cl-list &rest cl-keys)
759 "Find the first item whose cdr does not satisfy PREDICATE in LIST.
760 \nKeywords supported: :key
761 \n(fn PREDICATE LIST [KEYWORD VALUE]...)"
762 (apply 'cl-rassoc nil cl-list :if-not cl-pred cl-keys))
763
764 ;;;###autoload
765 (defun cl-union (cl-list1 cl-list2 &rest cl-keys)
766 "Combine LIST1 and LIST2 using a set-union operation.
767 The resulting list contains all items that appear in either LIST1 or LIST2.
768 This is a non-destructive function; it makes a copy of the data if necessary
769 to avoid corrupting the original LIST1 and LIST2.
770 \nKeywords supported: :test :test-not :key
771 \n(fn LIST1 LIST2 [KEYWORD VALUE]...)"
772 (cond ((null cl-list1) cl-list2) ((null cl-list2) cl-list1)
773 ((equal cl-list1 cl-list2) cl-list1)
774 (t
775 (or (>= (length cl-list1) (length cl-list2))
776 (setq cl-list1 (prog1 cl-list2 (setq cl-list2 cl-list1))))
777 (while cl-list2
778 (if (or cl-keys (numberp (car cl-list2)))
779 (setq cl-list1 (apply 'cl-adjoin (car cl-list2) cl-list1 cl-keys))
780 (or (memq (car cl-list2) cl-list1)
781 (push (car cl-list2) cl-list1)))
782 (pop cl-list2))
783 cl-list1)))
784
785 ;;;###autoload
786 (defun cl-nunion (cl-list1 cl-list2 &rest cl-keys)
787 "Combine LIST1 and LIST2 using a set-union operation.
788 The resulting list contains all items that appear in either LIST1 or LIST2.
789 This is a destructive function; it reuses the storage of LIST1 and LIST2
790 whenever possible.
791 \nKeywords supported: :test :test-not :key
792 \n(fn LIST1 LIST2 [KEYWORD VALUE]...)"
793 (cond ((null cl-list1) cl-list2) ((null cl-list2) cl-list1)
794 (t (apply 'cl-union cl-list1 cl-list2 cl-keys))))
795
796 ;;;###autoload
797 (defun cl-intersection (cl-list1 cl-list2 &rest cl-keys)
798 "Combine LIST1 and LIST2 using a set-intersection operation.
799 The resulting list contains all items that appear in both LIST1 and LIST2.
800 This is a non-destructive function; it makes a copy of the data if necessary
801 to avoid corrupting the original LIST1 and LIST2.
802 \nKeywords supported: :test :test-not :key
803 \n(fn LIST1 LIST2 [KEYWORD VALUE]...)"
804 (and cl-list1 cl-list2
805 (if (equal cl-list1 cl-list2) cl-list1
806 (cl--parsing-keywords (:key) (:test :test-not)
807 (let ((cl-res nil))
808 (or (>= (length cl-list1) (length cl-list2))
809 (setq cl-list1 (prog1 cl-list2 (setq cl-list2 cl-list1))))
810 (while cl-list2
811 (if (if (or cl-keys (numberp (car cl-list2)))
812 (apply 'cl-member (cl--check-key (car cl-list2))
813 cl-list1 cl-keys)
814 (memq (car cl-list2) cl-list1))
815 (push (car cl-list2) cl-res))
816 (pop cl-list2))
817 cl-res)))))
818
819 ;;;###autoload
820 (defun cl-nintersection (cl-list1 cl-list2 &rest cl-keys)
821 "Combine LIST1 and LIST2 using a set-intersection operation.
822 The resulting list contains all items that appear in both LIST1 and LIST2.
823 This is a destructive function; it reuses the storage of LIST1 and LIST2
824 whenever possible.
825 \nKeywords supported: :test :test-not :key
826 \n(fn LIST1 LIST2 [KEYWORD VALUE]...)"
827 (and cl-list1 cl-list2 (apply 'cl-intersection cl-list1 cl-list2 cl-keys)))
828
829 ;;;###autoload
830 (defun cl-set-difference (cl-list1 cl-list2 &rest cl-keys)
831 "Combine LIST1 and LIST2 using a set-difference operation.
832 The resulting list contains all items that appear in LIST1 but not LIST2.
833 This is a non-destructive function; it makes a copy of the data if necessary
834 to avoid corrupting the original LIST1 and LIST2.
835 \nKeywords supported: :test :test-not :key
836 \n(fn LIST1 LIST2 [KEYWORD VALUE]...)"
837 (if (or (null cl-list1) (null cl-list2)) cl-list1
838 (cl--parsing-keywords (:key) (:test :test-not)
839 (let ((cl-res nil))
840 (while cl-list1
841 (or (if (or cl-keys (numberp (car cl-list1)))
842 (apply 'cl-member (cl--check-key (car cl-list1))
843 cl-list2 cl-keys)
844 (memq (car cl-list1) cl-list2))
845 (push (car cl-list1) cl-res))
846 (pop cl-list1))
847 cl-res))))
848
849 ;;;###autoload
850 (defun cl-nset-difference (cl-list1 cl-list2 &rest cl-keys)
851 "Combine LIST1 and LIST2 using a set-difference operation.
852 The resulting list contains all items that appear in LIST1 but not LIST2.
853 This is a destructive function; it reuses the storage of LIST1 and LIST2
854 whenever possible.
855 \nKeywords supported: :test :test-not :key
856 \n(fn LIST1 LIST2 [KEYWORD VALUE]...)"
857 (if (or (null cl-list1) (null cl-list2)) cl-list1
858 (apply 'cl-set-difference cl-list1 cl-list2 cl-keys)))
859
860 ;;;###autoload
861 (defun cl-set-exclusive-or (cl-list1 cl-list2 &rest cl-keys)
862 "Combine LIST1 and LIST2 using a set-exclusive-or operation.
863 The resulting list contains all items appearing in exactly one of LIST1, LIST2.
864 This is a non-destructive function; it makes a copy of the data if necessary
865 to avoid corrupting the original LIST1 and LIST2.
866 \nKeywords supported: :test :test-not :key
867 \n(fn LIST1 LIST2 [KEYWORD VALUE]...)"
868 (cond ((null cl-list1) cl-list2) ((null cl-list2) cl-list1)
869 ((equal cl-list1 cl-list2) nil)
870 (t (append (apply 'cl-set-difference cl-list1 cl-list2 cl-keys)
871 (apply 'cl-set-difference cl-list2 cl-list1 cl-keys)))))
872
873 ;;;###autoload
874 (defun cl-nset-exclusive-or (cl-list1 cl-list2 &rest cl-keys)
875 "Combine LIST1 and LIST2 using a set-exclusive-or operation.
876 The resulting list contains all items appearing in exactly one of LIST1, LIST2.
877 This is a destructive function; it reuses the storage of LIST1 and LIST2
878 whenever possible.
879 \nKeywords supported: :test :test-not :key
880 \n(fn LIST1 LIST2 [KEYWORD VALUE]...)"
881 (cond ((null cl-list1) cl-list2) ((null cl-list2) cl-list1)
882 ((equal cl-list1 cl-list2) nil)
883 (t (nconc (apply 'cl-nset-difference cl-list1 cl-list2 cl-keys)
884 (apply 'cl-nset-difference cl-list2 cl-list1 cl-keys)))))
885
886 ;;;###autoload
887 (defun cl-subsetp (cl-list1 cl-list2 &rest cl-keys)
888 "Return true if LIST1 is a subset of LIST2.
889 I.e., if every element of LIST1 also appears in LIST2.
890 \nKeywords supported: :test :test-not :key
891 \n(fn LIST1 LIST2 [KEYWORD VALUE]...)"
892 (cond ((null cl-list1) t) ((null cl-list2) nil)
893 ((equal cl-list1 cl-list2) t)
894 (t (cl--parsing-keywords (:key) (:test :test-not)
895 (while (and cl-list1
896 (apply 'cl-member (cl--check-key (car cl-list1))
897 cl-list2 cl-keys))
898 (pop cl-list1))
899 (null cl-list1)))))
900
901 ;;;###autoload
902 (defun cl-subst-if (cl-new cl-pred cl-tree &rest cl-keys)
903 "Substitute NEW for elements matching PREDICATE in TREE (non-destructively).
904 Return a copy of TREE with all matching elements replaced by NEW.
905 \nKeywords supported: :key
906 \n(fn NEW PREDICATE TREE [KEYWORD VALUE]...)"
907 (apply 'cl-sublis (list (cons nil cl-new)) cl-tree :if cl-pred cl-keys))
908
909 ;;;###autoload
910 (defun cl-subst-if-not (cl-new cl-pred cl-tree &rest cl-keys)
911 "Substitute NEW for elts not matching PREDICATE in TREE (non-destructively).
912 Return a copy of TREE with all non-matching elements replaced by NEW.
913 \nKeywords supported: :key
914 \n(fn NEW PREDICATE TREE [KEYWORD VALUE]...)"
915 (apply 'cl-sublis (list (cons nil cl-new)) cl-tree :if-not cl-pred cl-keys))
916
917 ;;;###autoload
918 (defun cl-nsubst (cl-new cl-old cl-tree &rest cl-keys)
919 "Substitute NEW for OLD everywhere in TREE (destructively).
920 Any element of TREE which is `eql' to OLD is changed to NEW (via a call
921 to `setcar').
922 \nKeywords supported: :test :test-not :key
923 \n(fn NEW OLD TREE [KEYWORD VALUE]...)"
924 (apply 'cl-nsublis (list (cons cl-old cl-new)) cl-tree cl-keys))
925
926 ;;;###autoload
927 (defun cl-nsubst-if (cl-new cl-pred cl-tree &rest cl-keys)
928 "Substitute NEW for elements matching PREDICATE in TREE (destructively).
929 Any element of TREE which matches is changed to NEW (via a call to `setcar').
930 \nKeywords supported: :key
931 \n(fn NEW PREDICATE TREE [KEYWORD VALUE]...)"
932 (apply 'cl-nsublis (list (cons nil cl-new)) cl-tree :if cl-pred cl-keys))
933
934 ;;;###autoload
935 (defun cl-nsubst-if-not (cl-new cl-pred cl-tree &rest cl-keys)
936 "Substitute NEW for elements not matching PREDICATE in TREE (destructively).
937 Any element of TREE which matches is changed to NEW (via a call to `setcar').
938 \nKeywords supported: :key
939 \n(fn NEW PREDICATE TREE [KEYWORD VALUE]...)"
940 (apply 'cl-nsublis (list (cons nil cl-new)) cl-tree :if-not cl-pred cl-keys))
941
942 (defvar cl--alist)
943
944 ;;;###autoload
945 (defun cl-sublis (cl-alist cl-tree &rest cl-keys)
946 "Perform substitutions indicated by ALIST in TREE (non-destructively).
947 Return a copy of TREE with all matching elements replaced.
948 \nKeywords supported: :test :test-not :key
949 \n(fn ALIST TREE [KEYWORD VALUE]...)"
950 (cl--parsing-keywords (:test :test-not :key :if :if-not) ()
951 (let ((cl--alist cl-alist))
952 (cl--sublis-rec cl-tree))))
953
954 (defun cl--sublis-rec (cl-tree) ;Uses cl--alist cl-key/test*/if*.
955 (let ((cl-temp (cl--check-key cl-tree)) (cl-p cl--alist))
956 (while (and cl-p (not (cl--check-test-nokey (car (car cl-p)) cl-temp)))
957 (setq cl-p (cdr cl-p)))
958 (if cl-p (cdr (car cl-p))
959 (if (consp cl-tree)
960 (let ((cl-a (cl--sublis-rec (car cl-tree)))
961 (cl-d (cl--sublis-rec (cdr cl-tree))))
962 (if (and (eq cl-a (car cl-tree)) (eq cl-d (cdr cl-tree)))
963 cl-tree
964 (cons cl-a cl-d)))
965 cl-tree))))
966
967 ;;;###autoload
968 (defun cl-nsublis (cl-alist cl-tree &rest cl-keys)
969 "Perform substitutions indicated by ALIST in TREE (destructively).
970 Any matching element of TREE is changed via a call to `setcar'.
971 \nKeywords supported: :test :test-not :key
972 \n(fn ALIST TREE [KEYWORD VALUE]...)"
973 (cl--parsing-keywords (:test :test-not :key :if :if-not) ()
974 (let ((cl-hold (list cl-tree))
975 (cl--alist cl-alist))
976 (cl--nsublis-rec cl-hold)
977 (car cl-hold))))
978
979 (defun cl--nsublis-rec (cl-tree) ;Uses cl--alist cl-key/test*/if*.
980 (while (consp cl-tree)
981 (let ((cl-temp (cl--check-key (car cl-tree))) (cl-p cl--alist))
982 (while (and cl-p (not (cl--check-test-nokey (car (car cl-p)) cl-temp)))
983 (setq cl-p (cdr cl-p)))
984 (if cl-p (setcar cl-tree (cdr (car cl-p)))
985 (if (consp (car cl-tree)) (cl--nsublis-rec (car cl-tree))))
986 (setq cl-temp (cl--check-key (cdr cl-tree)) cl-p cl--alist)
987 (while (and cl-p (not (cl--check-test-nokey (car (car cl-p)) cl-temp)))
988 (setq cl-p (cdr cl-p)))
989 (if cl-p
990 (progn (setcdr cl-tree (cdr (car cl-p))) (setq cl-tree nil))
991 (setq cl-tree (cdr cl-tree))))))
992
993 ;;;###autoload
994 (defun cl-tree-equal (cl-x cl-y &rest cl-keys)
995 "Return t if trees TREE1 and TREE2 have `eql' leaves.
996 Atoms are compared by `eql'; cons cells are compared recursively.
997 \nKeywords supported: :test :test-not :key
998 \n(fn TREE1 TREE2 [KEYWORD VALUE]...)"
999 (cl--parsing-keywords (:test :test-not :key) ()
1000 (cl--tree-equal-rec cl-x cl-y)))
1001
1002 (defun cl--tree-equal-rec (cl-x cl-y) ;Uses cl-key/test*.
1003 (while (and (consp cl-x) (consp cl-y)
1004 (cl--tree-equal-rec (car cl-x) (car cl-y)))
1005 (setq cl-x (cdr cl-x) cl-y (cdr cl-y)))
1006 (and (not (consp cl-x)) (not (consp cl-y)) (cl--check-match cl-x cl-y)))
1007
1008
1009 (run-hooks 'cl-seq-load-hook)
1010
1011 ;; Local variables:
1012 ;; byte-compile-dynamic: t
1013 ;; generated-autoload-file: "cl-loaddefs.el"
1014 ;; End:
1015
1016 ;;; cl-seq.el ends here