comparison lisp/cl-seq.el @ 2153:393039450288

[xemacs-hg @ 2004-06-26 21:25:23 by james] Synch with Emacs 21.3.
author james
date Sat, 26 Jun 2004 21:25:24 +0000
parents 023b83f4e54b
children 6772ce4d982b
comparison
equal deleted inserted replaced
2152:d93fedcbf6be 2153:393039450288
22 ;; You should have received a copy of the GNU General Public License 22 ;; You should have received a copy of the GNU General Public License
23 ;; along with XEmacs; see the file COPYING. If not, write to the Free 23 ;; along with XEmacs; see the file COPYING. If not, write to the Free
24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 ;; 02111-1307, USA. 25 ;; 02111-1307, USA.
26 26
27 ;;; Synched up with: FSF 19.34. 27 ;;; Synched up with: FSF 21.3.
28 28
29 ;;; Commentary: 29 ;;; Commentary:
30 30
31 ;; This file is dumped with XEmacs. 31 ;; This file is dumped with XEmacs.
32 32
49 49
50 ;;; Code: 50 ;;; Code:
51 51
52 (or (memq 'cl-19 features) 52 (or (memq 'cl-19 features)
53 (error "Tried to load `cl-seq' before `cl'!")) 53 (error "Tried to load `cl-seq' before `cl'!"))
54
55
56 ;;; We define these here so that this file can compile without having
57 ;;; loaded the cl.el file already.
58
59 (defmacro cl-push (x place) (list 'setq place (list 'cons x place)))
60 (defmacro cl-pop (place)
61 (list 'car (list 'prog1 place (list 'setq place (list 'cdr place)))))
62 54
63 55
64 ;;; Keyword parsing. This is special-cased here so that we can compile 56 ;;; Keyword parsing. This is special-cased here so that we can compile
65 ;;; this file independent from cl-macs. 57 ;;; this file independent from cl-macs.
66 58
88 (function 80 (function
89 (lambda (x) 81 (lambda (x)
90 (let* ((var (if (consp x) (car x) x)) 82 (let* ((var (if (consp x) (car x) x))
91 (mem (list 'car (list 'cdr (list 'memq (list 'quote var) 83 (mem (list 'car (list 'cdr (list 'memq (list 'quote var)
92 'cl-keys))))) 84 'cl-keys)))))
93 (if (eq var ':test-not) 85 (if (eq var :test-not)
94 (setq mem (list 'and mem (list 'setq 'cl-test mem) t))) 86 (setq mem (list 'and mem (list 'setq 'cl-test mem) t)))
95 (if (eq var ':if-not) 87 (if (eq var :if-not)
96 (setq mem (list 'and mem (list 'setq 'cl-if mem) t))) 88 (setq mem (list 'and mem (list 'setq 'cl-if mem) t)))
97 (list (intern 89 (list (intern
98 (format "cl-%s" (substring (symbol-name var) 1))) 90 (format "cl-%s" (substring (symbol-name var) 1)))
99 (if (consp x) (list 'or mem (car (cdr x))) mem))))) 91 (if (consp x) (list 'or mem (car (cdr x))) mem)))))
100 kwords) 92 kwords)
159 Keywords supported: :start :end :from-end :initial-value :key" 151 Keywords supported: :start :end :from-end :initial-value :key"
160 (cl-parsing-keywords (:from-end (:start 0) :end :initial-value :key) () 152 (cl-parsing-keywords (:from-end (:start 0) :end :initial-value :key) ()
161 (or (listp cl-seq) (setq cl-seq (append cl-seq nil))) 153 (or (listp cl-seq) (setq cl-seq (append cl-seq nil)))
162 (setq cl-seq (subseq cl-seq cl-start cl-end)) 154 (setq cl-seq (subseq cl-seq cl-start cl-end))
163 (if cl-from-end (setq cl-seq (nreverse cl-seq))) 155 (if cl-from-end (setq cl-seq (nreverse cl-seq)))
164 (let ((cl-accum (cond ((memq ':initial-value cl-keys) cl-initial-value) 156 (let ((cl-accum (cond ((memq :initial-value cl-keys) cl-initial-value)
165 (cl-seq (cl-check-key (cl-pop cl-seq))) 157 (cl-seq (cl-check-key (pop cl-seq)))
166 (t (funcall cl-func))))) 158 (t (funcall cl-func)))))
167 (if cl-from-end 159 (if cl-from-end
168 (while cl-seq 160 (while cl-seq
169 (setq cl-accum (funcall cl-func (cl-check-key (cl-pop cl-seq)) 161 (setq cl-accum (funcall cl-func (cl-check-key (pop cl-seq))
170 cl-accum))) 162 cl-accum)))
171 (while cl-seq 163 (while cl-seq
172 (setq cl-accum (funcall cl-func cl-accum 164 (setq cl-accum (funcall cl-func cl-accum
173 (cl-check-key (cl-pop cl-seq)))))) 165 (cl-check-key (pop cl-seq))))))
174 cl-accum))) 166 cl-accum)))
175 167
176 (defun fill (seq item &rest cl-keys) 168 (defun fill (seq item &rest cl-keys)
177 "Fill the elements of SEQ with ITEM. 169 "Fill the elements of SEQ with ITEM.
178 Keywords supported: :start :end" 170 Keywords supported: :start :end"
245 (let ((cl-i (cl-position cl-item cl-seq cl-start cl-end 237 (let ((cl-i (cl-position cl-item cl-seq cl-start cl-end
246 cl-from-end))) 238 cl-from-end)))
247 (if cl-i 239 (if cl-i
248 (let ((cl-res (apply 'delete* cl-item (append cl-seq nil) 240 (let ((cl-res (apply 'delete* cl-item (append cl-seq nil)
249 (append (if cl-from-end 241 (append (if cl-from-end
250 (list ':end (1+ cl-i)) 242 (list :end (1+ cl-i))
251 (list ':start cl-i)) 243 (list :start cl-i))
252 cl-keys)))) 244 cl-keys))))
253 (if (listp cl-seq) cl-res 245 (if (listp cl-seq) cl-res
254 (if (stringp cl-seq) (concat cl-res) (vconcat cl-res)))) 246 (if (stringp cl-seq) (concat cl-res) (vconcat cl-res))))
255 cl-seq)) 247 cl-seq))
256 (setq cl-end (- (or cl-end 8000000) cl-start)) 248 (setq cl-end (- (or cl-end 8000000) cl-start))
269 (nconc (ldiff cl-seq cl-p) 261 (nconc (ldiff cl-seq cl-p)
270 (if (= cl-count 1) (cdr cl-p) 262 (if (= cl-count 1) (cdr cl-p)
271 (and (cdr cl-p) 263 (and (cdr cl-p)
272 (apply 'delete* cl-item 264 (apply 'delete* cl-item
273 (copy-sequence (cdr cl-p)) 265 (copy-sequence (cdr cl-p))
274 ':start 0 ':end (1- cl-end) 266 :start 0 :end (1- cl-end)
275 ':count (1- cl-count) cl-keys)))) 267 :count (1- cl-count) cl-keys))))
276 cl-seq)) 268 cl-seq))
277 cl-seq))))) 269 cl-seq)))))
278 270
279 (defun remove-if (cl-pred cl-list &rest cl-keys) 271 (defun remove-if (cl-pred cl-list &rest cl-keys)
280 "Remove all items satisfying PREDICATE in SEQ. 272 "Remove all items satisfying PREDICATE in SEQ.
281 This is a non-destructive function; it makes a copy of SEQ if necessary 273 This is a non-destructive function; it makes a copy of SEQ if necessary
282 to avoid corrupting the original SEQ. 274 to avoid corrupting the original SEQ.
283 Keywords supported: :key :count :start :end :from-end" 275 Keywords supported: :key :count :start :end :from-end"
284 (apply 'remove* nil cl-list ':if cl-pred cl-keys)) 276 (apply 'remove* nil cl-list :if cl-pred cl-keys))
285 277
286 (defun remove-if-not (cl-pred cl-list &rest cl-keys) 278 (defun remove-if-not (cl-pred cl-list &rest cl-keys)
287 "Remove all items not satisfying PREDICATE in SEQ. 279 "Remove all items not satisfying PREDICATE in SEQ.
288 This is a non-destructive function; it makes a copy of SEQ if necessary 280 This is a non-destructive function; it makes a copy of SEQ if necessary
289 to avoid corrupting the original SEQ. 281 to avoid corrupting the original SEQ.
290 Keywords supported: :key :count :start :end :from-end" 282 Keywords supported: :key :count :start :end :from-end"
291 (apply 'remove* nil cl-list ':if-not cl-pred cl-keys)) 283 (apply 'remove* nil cl-list :if-not cl-pred cl-keys))
292 284
293 (defun delete* (cl-item cl-seq &rest cl-keys) 285 (defun delete* (cl-item cl-seq &rest cl-keys)
294 "Remove all occurrences of ITEM in SEQ. 286 "Remove all occurrences of ITEM in SEQ.
295 This is a destructive function; it reuses the storage of SEQ whenever possible. 287 This is a destructive function; it reuses the storage of SEQ whenever possible.
296 Keywords supported: :test :test-not :key :count :start :end :from-end" 288 Keywords supported: :test :test-not :key :count :start :end :from-end"
334 326
335 (defun delete-if (cl-pred cl-list &rest cl-keys) 327 (defun delete-if (cl-pred cl-list &rest cl-keys)
336 "Remove all items satisfying PREDICATE in SEQ. 328 "Remove all items satisfying PREDICATE in SEQ.
337 This is a destructive function; it reuses the storage of SEQ whenever possible. 329 This is a destructive function; it reuses the storage of SEQ whenever possible.
338 Keywords supported: :key :count :start :end :from-end" 330 Keywords supported: :key :count :start :end :from-end"
339 (apply 'delete* nil cl-list ':if cl-pred cl-keys)) 331 (apply 'delete* nil cl-list :if cl-pred cl-keys))
340 332
341 (defun delete-if-not (cl-pred cl-list &rest cl-keys) 333 (defun delete-if-not (cl-pred cl-list &rest cl-keys)
342 "Remove all items not satisfying PREDICATE in SEQ. 334 "Remove all items not satisfying PREDICATE in SEQ.
343 This is a destructive function; it reuses the storage of SEQ whenever possible. 335 This is a destructive function; it reuses the storage of SEQ whenever possible.
344 Keywords supported: :key :count :start :end :from-end" 336 Keywords supported: :key :count :start :end :from-end"
345 (apply 'delete* nil cl-list ':if-not cl-pred cl-keys)) 337 (apply 'delete* nil cl-list :if-not cl-pred cl-keys))
346 338
347 (or (and (fboundp 'delete) (subrp (symbol-function 'delete))) 339 ;; XEmacs change: this is in subr.el in Emacs
348 (defalias 'delete (function (lambda (x y) (delete* x y ':test 'equal)))))
349
350 (defun remove (cl-item cl-seq) 340 (defun remove (cl-item cl-seq)
351 "Remove all occurrences of ITEM in SEQ, testing with `equal' 341 "Remove all occurrences of ITEM in SEQ, testing with `equal'
352 This is a non-destructive function; it makes a copy of SEQ if necessary 342 This is a non-destructive function; it makes a copy of SEQ if necessary
353 to avoid corrupting the original SEQ. 343 to avoid corrupting the original SEQ.
354 Also see: `remove*', `delete', `delete*'" 344 Also see: `remove*', `delete', `delete*'"
355 (remove* cl-item cl-seq ':test 'equal)) 345 (remove* cl-item cl-seq ':test 'equal))
356 346
347 ;; XEmacs change: this is in subr.el in Emacs
357 (defun remq (cl-elt cl-list) 348 (defun remq (cl-elt cl-list)
358 "Remove all occurrences of ELT in LIST, comparing with `eq'. 349 "Remove all occurrences of ELT in LIST, comparing with `eq'.
359 This is a non-destructive function; it makes a copy of LIST to avoid 350 This is a non-destructive function; it makes a copy of LIST to avoid
360 corrupting the original LIST. 351 corrupting the original LIST.
361 Also see: `delq', `delete', `delete*', `remove', `remove*'." 352 Also see: `delq', `delete', `delete*', `remove', `remove*'."
428 cl-seq 419 cl-seq
429 (setq cl-seq (copy-sequence cl-seq)) 420 (setq cl-seq (copy-sequence cl-seq))
430 (or cl-from-end 421 (or cl-from-end
431 (progn (cl-set-elt cl-seq cl-i cl-new) 422 (progn (cl-set-elt cl-seq cl-i cl-new)
432 (setq cl-i (1+ cl-i) cl-count (1- cl-count)))) 423 (setq cl-i (1+ cl-i) cl-count (1- cl-count))))
433 (apply 'nsubstitute cl-new cl-old cl-seq ':count cl-count 424 (apply 'nsubstitute cl-new cl-old cl-seq :count cl-count
434 ':start cl-i cl-keys)))))) 425 :start cl-i cl-keys))))))
435 426
436 (defun substitute-if (cl-new cl-pred cl-list &rest cl-keys) 427 (defun substitute-if (cl-new cl-pred cl-list &rest cl-keys)
437 "Substitute NEW for all items satisfying PREDICATE in SEQ. 428 "Substitute NEW for all items satisfying PREDICATE in SEQ.
438 This is a non-destructive function; it makes a copy of SEQ if necessary 429 This is a non-destructive function; it makes a copy of SEQ if necessary
439 to avoid corrupting the original SEQ. 430 to avoid corrupting the original SEQ.
440 Keywords supported: :key :count :start :end :from-end" 431 Keywords supported: :key :count :start :end :from-end"
441 (apply 'substitute cl-new nil cl-list ':if cl-pred cl-keys)) 432 (apply 'substitute cl-new nil cl-list :if cl-pred cl-keys))
442 433
443 (defun substitute-if-not (cl-new cl-pred cl-list &rest cl-keys) 434 (defun substitute-if-not (cl-new cl-pred cl-list &rest cl-keys)
444 "Substitute NEW for all items not satisfying PREDICATE in SEQ. 435 "Substitute NEW for all items not satisfying PREDICATE in SEQ.
445 This is a non-destructive function; it makes a copy of SEQ if necessary 436 This is a non-destructive function; it makes a copy of SEQ if necessary
446 to avoid corrupting the original SEQ. 437 to avoid corrupting the original SEQ.
447 Keywords supported: :key :count :start :end :from-end" 438 Keywords supported: :key :count :start :end :from-end"
448 (apply 'substitute cl-new nil cl-list ':if-not cl-pred cl-keys)) 439 (apply 'substitute cl-new nil cl-list :if-not cl-pred cl-keys))
449 440
450 (defun nsubstitute (cl-new cl-old cl-seq &rest cl-keys) 441 (defun nsubstitute (cl-new cl-old cl-seq &rest cl-keys)
451 "Substitute NEW for OLD in SEQ. 442 "Substitute NEW for OLD in SEQ.
452 This is a destructive function; it reuses the storage of SEQ whenever possible. 443 This is a destructive function; it reuses the storage of SEQ whenever possible.
453 Keywords supported: :test :test-not :key :count :start :end :from-end" 444 Keywords supported: :test :test-not :key :count :start :end :from-end"
481 472
482 (defun nsubstitute-if (cl-new cl-pred cl-list &rest cl-keys) 473 (defun nsubstitute-if (cl-new cl-pred cl-list &rest cl-keys)
483 "Substitute NEW for all items satisfying PREDICATE in SEQ. 474 "Substitute NEW for all items satisfying PREDICATE in SEQ.
484 This is a destructive function; it reuses the storage of SEQ whenever possible. 475 This is a destructive function; it reuses the storage of SEQ whenever possible.
485 Keywords supported: :key :count :start :end :from-end" 476 Keywords supported: :key :count :start :end :from-end"
486 (apply 'nsubstitute cl-new nil cl-list ':if cl-pred cl-keys)) 477 (apply 'nsubstitute cl-new nil cl-list :if cl-pred cl-keys))
487 478
488 (defun nsubstitute-if-not (cl-new cl-pred cl-list &rest cl-keys) 479 (defun nsubstitute-if-not (cl-new cl-pred cl-list &rest cl-keys)
489 "Substitute NEW for all items not satisfying PREDICATE in SEQ. 480 "Substitute NEW for all items not satisfying PREDICATE in SEQ.
490 This is a destructive function; it reuses the storage of SEQ whenever possible. 481 This is a destructive function; it reuses the storage of SEQ whenever possible.
491 Keywords supported: :key :count :start :end :from-end" 482 Keywords supported: :key :count :start :end :from-end"
492 (apply 'nsubstitute cl-new nil cl-list ':if-not cl-pred cl-keys)) 483 (apply 'nsubstitute cl-new nil cl-list :if-not cl-pred cl-keys))
493 484
494 (defun find (cl-item cl-seq &rest cl-keys) 485 (defun find (cl-item cl-seq &rest cl-keys)
495 "Find the first occurrence of ITEM in LIST. 486 "Find the first occurrence of ITEM in LIST.
496 Return the matching ITEM, or nil if not found. 487 Return the matching ITEM, or nil if not found.
497 Keywords supported: :test :test-not :key :start :end :from-end" 488 Keywords supported: :test :test-not :key :start :end :from-end"
500 491
501 (defun find-if (cl-pred cl-list &rest cl-keys) 492 (defun find-if (cl-pred cl-list &rest cl-keys)
502 "Find the first item satisfying PREDICATE in LIST. 493 "Find the first item satisfying PREDICATE in LIST.
503 Return the matching ITEM, or nil if not found. 494 Return the matching ITEM, or nil if not found.
504 Keywords supported: :key :start :end :from-end" 495 Keywords supported: :key :start :end :from-end"
505 (apply 'find nil cl-list ':if cl-pred cl-keys)) 496 (apply 'find nil cl-list :if cl-pred cl-keys))
506 497
507 (defun find-if-not (cl-pred cl-list &rest cl-keys) 498 (defun find-if-not (cl-pred cl-list &rest cl-keys)
508 "Find the first item not satisfying PREDICATE in LIST. 499 "Find the first item not satisfying PREDICATE in LIST.
509 Return the matching ITEM, or nil if not found. 500 Return the matching ITEM, or nil if not found.
510 Keywords supported: :key :start :end :from-end" 501 Keywords supported: :key :start :end :from-end"
511 (apply 'find nil cl-list ':if-not cl-pred cl-keys)) 502 (apply 'find nil cl-list :if-not cl-pred cl-keys))
512 503
513 (defun position (cl-item cl-seq &rest cl-keys) 504 (defun position (cl-item cl-seq &rest cl-keys)
514 "Find the first occurrence of ITEM in LIST. 505 "Find the first occurrence of ITEM in LIST.
515 Return the index of the matching item, or nil if not found. 506 Return the index of the matching item, or nil if not found.
516 Keywords supported: :test :test-not :key :start :end :from-end" 507 Keywords supported: :test :test-not :key :start :end :from-end"
541 532
542 (defun position-if (cl-pred cl-list &rest cl-keys) 533 (defun position-if (cl-pred cl-list &rest cl-keys)
543 "Find the first item satisfying PREDICATE in LIST. 534 "Find the first item satisfying PREDICATE in LIST.
544 Return the index of the matching item, or nil if not found. 535 Return the index of the matching item, or nil if not found.
545 Keywords supported: :key :start :end :from-end" 536 Keywords supported: :key :start :end :from-end"
546 (apply 'position nil cl-list ':if cl-pred cl-keys)) 537 (apply 'position nil cl-list :if cl-pred cl-keys))
547 538
548 (defun position-if-not (cl-pred cl-list &rest cl-keys) 539 (defun position-if-not (cl-pred cl-list &rest cl-keys)
549 "Find the first item not satisfying PREDICATE in LIST. 540 "Find the first item not satisfying PREDICATE in LIST.
550 Return the index of the matching item, or nil if not found. 541 Return the index of the matching item, or nil if not found.
551 Keywords supported: :key :start :end :from-end" 542 Keywords supported: :key :start :end :from-end"
552 (apply 'position nil cl-list ':if-not cl-pred cl-keys)) 543 (apply 'position nil cl-list :if-not cl-pred cl-keys))
553 544
554 (defun count (cl-item cl-seq &rest cl-keys) 545 (defun count (cl-item cl-seq &rest cl-keys)
555 "Count the number of occurrences of ITEM in LIST. 546 "Count the number of occurrences of ITEM in LIST.
556 Keywords supported: :test :test-not :key :start :end" 547 Keywords supported: :test :test-not :key :start :end"
557 (cl-parsing-keywords (:test :test-not :key :if :if-not (:start 0) :end) () 548 (cl-parsing-keywords (:test :test-not :key :if :if-not (:start 0) :end) ()
558 (let ((cl-count 0) cl-x) 549 (let ((cl-count 0) cl-x)
559 (or cl-end (setq cl-end (length cl-seq))) 550 (or cl-end (setq cl-end (length cl-seq)))
560 (if (consp cl-seq) (setq cl-seq (nthcdr cl-start cl-seq))) 551 (if (consp cl-seq) (setq cl-seq (nthcdr cl-start cl-seq)))
561 (while (< cl-start cl-end) 552 (while (< cl-start cl-end)
562 (setq cl-x (if (consp cl-seq) (cl-pop cl-seq) (aref cl-seq cl-start))) 553 (setq cl-x (if (consp cl-seq) (pop cl-seq) (aref cl-seq cl-start)))
563 (if (cl-check-test cl-item cl-x) (setq cl-count (1+ cl-count))) 554 (if (cl-check-test cl-item cl-x) (setq cl-count (1+ cl-count)))
564 (setq cl-start (1+ cl-start))) 555 (setq cl-start (1+ cl-start)))
565 cl-count))) 556 cl-count)))
566 557
567 (defun count-if (cl-pred cl-list &rest cl-keys) 558 (defun count-if (cl-pred cl-list &rest cl-keys)
568 "Count the number of items satisfying PREDICATE in LIST. 559 "Count the number of items satisfying PREDICATE in LIST.
569 Keywords supported: :key :start :end" 560 Keywords supported: :key :start :end"
570 (apply 'count nil cl-list ':if cl-pred cl-keys)) 561 (apply 'count nil cl-list :if cl-pred cl-keys))
571 562
572 (defun count-if-not (cl-pred cl-list &rest cl-keys) 563 (defun count-if-not (cl-pred cl-list &rest cl-keys)
573 "Count the number of items not satisfying PREDICATE in LIST. 564 "Count the number of items not satisfying PREDICATE in LIST.
574 Keywords supported: :key :start :end" 565 Keywords supported: :key :start :end"
575 (apply 'count nil cl-list ':if-not cl-pred cl-keys)) 566 (apply 'count nil cl-list :if-not cl-pred cl-keys))
576 567
577 (defun mismatch (cl-seq1 cl-seq2 &rest cl-keys) 568 (defun mismatch (cl-seq1 cl-seq2 &rest cl-keys)
578 "Compare SEQ1 with SEQ2, return index of first mismatching element. 569 "Compare SEQ1 with SEQ2, return index of first mismatching element.
579 Return nil if the sequences match. If one sequence is a prefix of the 570 Return nil if the sequences match. If one sequence is a prefix of the
580 other, the return value indicates the end of the shorted sequence. 571 other, the return value indicates the end of the shorter sequence.
581 Keywords supported: :test :test-not :key :start1 :end1 :start2 :end2 :from-end" 572 Keywords supported: :test :test-not :key :start1 :end1 :start2 :end2 :from-end"
582 (cl-parsing-keywords (:test :test-not :key :from-end 573 (cl-parsing-keywords (:test :test-not :key :from-end
583 (:start1 0) :end1 (:start2 0) :end2) () 574 (:start1 0) :end1 (:start2 0) :end2) ()
584 (or cl-end1 (setq cl-end1 (length cl-seq1))) 575 (or cl-end1 (setq cl-end1 (length cl-seq1)))
585 (or cl-end2 (setq cl-end2 (length cl-seq2))) 576 (or cl-end2 (setq cl-end2 (length cl-seq2)))
620 (setq cl-end2 (- cl-end2 (1- cl-len))) 611 (setq cl-end2 (- cl-end2 (1- cl-len)))
621 (while (and (< cl-start2 cl-end2) 612 (while (and (< cl-start2 cl-end2)
622 (setq cl-pos (cl-position cl-first cl-seq2 613 (setq cl-pos (cl-position cl-first cl-seq2
623 cl-start2 cl-end2 cl-from-end)) 614 cl-start2 cl-end2 cl-from-end))
624 (apply 'mismatch cl-seq1 cl-seq2 615 (apply 'mismatch cl-seq1 cl-seq2
625 ':start1 (1+ cl-start1) ':end1 cl-end1 616 :start1 (1+ cl-start1) :end1 cl-end1
626 ':start2 (1+ cl-pos) ':end2 (+ cl-pos cl-len) 617 :start2 (1+ cl-pos) :end2 (+ cl-pos cl-len)
627 ':from-end nil cl-keys)) 618 :from-end nil cl-keys))
628 (if cl-from-end (setq cl-end2 cl-pos) (setq cl-start2 (1+ cl-pos)))) 619 (if cl-from-end (setq cl-end2 cl-pos) (setq cl-start2 (1+ cl-pos))))
629 (and (< cl-start2 cl-end2) cl-pos))))) 620 (and (< cl-start2 cl-end2) cl-pos)))))
630 621
631 (defun sort* (cl-seq cl-pred &rest cl-keys) 622 (defun sort* (cl-seq cl-pred &rest cl-keys)
632 "Sort the argument SEQUENCE according to PREDICATE. 623 "Sort the argument SEQUENCE according to PREDICATE.
657 (cl-parsing-keywords (:key) () 648 (cl-parsing-keywords (:key) ()
658 (let ((cl-res nil)) 649 (let ((cl-res nil))
659 (while (and cl-seq1 cl-seq2) 650 (while (and cl-seq1 cl-seq2)
660 (if (funcall cl-pred (cl-check-key (car cl-seq2)) 651 (if (funcall cl-pred (cl-check-key (car cl-seq2))
661 (cl-check-key (car cl-seq1))) 652 (cl-check-key (car cl-seq1)))
662 (cl-push (cl-pop cl-seq2) cl-res) 653 (push (pop cl-seq2) cl-res)
663 (cl-push (cl-pop cl-seq1) cl-res))) 654 (push (pop cl-seq1) cl-res)))
664 (coerce (nconc (nreverse cl-res) cl-seq1 cl-seq2) cl-type)))) 655 (coerce (nconc (nreverse cl-res) cl-seq1 cl-seq2) cl-type))))
665 656
666 ;;; See compiler macro in cl-macs.el 657 ;;; See compiler macro in cl-macs.el
667 (defun member* (cl-item cl-list &rest cl-keys) 658 (defun member* (cl-item cl-list &rest cl-keys)
668 "Find the first occurrence of ITEM in LIST. 659 "Find the first occurrence of ITEM in LIST.
679 670
680 (defun member-if (cl-pred cl-list &rest cl-keys) 671 (defun member-if (cl-pred cl-list &rest cl-keys)
681 "Find the first item satisfying PREDICATE in LIST. 672 "Find the first item satisfying PREDICATE in LIST.
682 Return the sublist of LIST whose car matches. 673 Return the sublist of LIST whose car matches.
683 Keywords supported: :key" 674 Keywords supported: :key"
684 (apply 'member* nil cl-list ':if cl-pred cl-keys)) 675 (apply 'member* nil cl-list :if cl-pred cl-keys))
685 676
686 (defun member-if-not (cl-pred cl-list &rest cl-keys) 677 (defun member-if-not (cl-pred cl-list &rest cl-keys)
687 "Find the first item not satisfying PREDICATE in LIST. 678 "Find the first item not satisfying PREDICATE in LIST.
688 Return the sublist of LIST whose car matches. 679 Return the sublist of LIST whose car matches.
689 Keywords supported: :key" 680 Keywords supported: :key"
690 (apply 'member* nil cl-list ':if-not cl-pred cl-keys)) 681 (apply 'member* nil cl-list :if-not cl-pred cl-keys))
691 682
692 (defun cl-adjoin (cl-item cl-list &rest cl-keys) 683 (defun cl-adjoin (cl-item cl-list &rest cl-keys)
693 (if (cl-parsing-keywords (:key) t 684 (if (cl-parsing-keywords (:key) t
694 (apply 'member* (cl-check-key cl-item) cl-list cl-keys)) 685 (apply 'member* (cl-check-key cl-item) cl-list cl-keys))
695 cl-list 686 cl-list
711 (assq cl-item cl-alist)))) 702 (assq cl-item cl-alist))))
712 703
713 (defun assoc-if (cl-pred cl-list &rest cl-keys) 704 (defun assoc-if (cl-pred cl-list &rest cl-keys)
714 "Find the first item whose car satisfies PREDICATE in LIST. 705 "Find the first item whose car satisfies PREDICATE in LIST.
715 Keywords supported: :key" 706 Keywords supported: :key"
716 (apply 'assoc* nil cl-list ':if cl-pred cl-keys)) 707 (apply 'assoc* nil cl-list :if cl-pred cl-keys))
717 708
718 (defun assoc-if-not (cl-pred cl-list &rest cl-keys) 709 (defun assoc-if-not (cl-pred cl-list &rest cl-keys)
719 "Find the first item whose car does not satisfy PREDICATE in LIST. 710 "Find the first item whose car does not satisfy PREDICATE in LIST.
720 Keywords supported: :key" 711 Keywords supported: :key"
721 (apply 'assoc* nil cl-list ':if-not cl-pred cl-keys)) 712 (apply 'assoc* nil cl-list :if-not cl-pred cl-keys))
722 713
723 (defun rassoc* (cl-item cl-alist &rest cl-keys) 714 (defun rassoc* (cl-item cl-alist &rest cl-keys)
724 "Find the first item whose cdr matches ITEM in LIST. 715 "Find the first item whose cdr matches ITEM in LIST.
725 Keywords supported: :test :test-not :key" 716 Keywords supported: :test :test-not :key"
726 (if (or cl-keys (numberp cl-item)) 717 (if (or cl-keys (numberp cl-item))
733 (rassq cl-item cl-alist))) 724 (rassq cl-item cl-alist)))
734 725
735 (defun rassoc-if (cl-pred cl-list &rest cl-keys) 726 (defun rassoc-if (cl-pred cl-list &rest cl-keys)
736 "Find the first item whose cdr satisfies PREDICATE in LIST. 727 "Find the first item whose cdr satisfies PREDICATE in LIST.
737 Keywords supported: :key" 728 Keywords supported: :key"
738 (apply 'rassoc* nil cl-list ':if cl-pred cl-keys)) 729 (apply 'rassoc* nil cl-list :if cl-pred cl-keys))
739 730
740 (defun rassoc-if-not (cl-pred cl-list &rest cl-keys) 731 (defun rassoc-if-not (cl-pred cl-list &rest cl-keys)
741 "Find the first item whose cdr does not satisfy PREDICATE in LIST. 732 "Find the first item whose cdr does not satisfy PREDICATE in LIST.
742 Keywords supported: :key" 733 Keywords supported: :key"
743 (apply 'rassoc* nil cl-list ':if-not cl-pred cl-keys)) 734 (apply 'rassoc* nil cl-list :if-not cl-pred cl-keys))
744 735
745 (defun union (cl-list1 cl-list2 &rest cl-keys) 736 (defun union (cl-list1 cl-list2 &rest cl-keys)
746 "Combine LIST1 and LIST2 using a set-union operation. 737 "Combine LIST1 and LIST2 using a set-union operation.
747 The result list contains all items that appear in either LIST1 or LIST2. 738 The result list contains all items that appear in either LIST1 or LIST2.
748 This is a non-destructive function; it makes a copy of the data if necessary 739 This is a non-destructive function; it makes a copy of the data if necessary
755 (setq cl-list1 (prog1 cl-list2 (setq cl-list2 cl-list1)))) 746 (setq cl-list1 (prog1 cl-list2 (setq cl-list2 cl-list1))))
756 (while cl-list2 747 (while cl-list2
757 (if (or cl-keys (numberp (car cl-list2))) 748 (if (or cl-keys (numberp (car cl-list2)))
758 (setq cl-list1 (apply 'adjoin (car cl-list2) cl-list1 cl-keys)) 749 (setq cl-list1 (apply 'adjoin (car cl-list2) cl-list1 cl-keys))
759 (or (memq (car cl-list2) cl-list1) 750 (or (memq (car cl-list2) cl-list1)
760 (cl-push (car cl-list2) cl-list1))) 751 (push (car cl-list2) cl-list1)))
761 (cl-pop cl-list2)) 752 (pop cl-list2))
762 cl-list1))) 753 cl-list1)))
763 754
764 (defun nunion (cl-list1 cl-list2 &rest cl-keys) 755 (defun nunion (cl-list1 cl-list2 &rest cl-keys)
765 "Combine LIST1 and LIST2 using a set-union operation. 756 "Combine LIST1 and LIST2 using a set-union operation.
766 The result list contains all items that appear in either LIST1 or LIST2. 757 The result list contains all items that appear in either LIST1 or LIST2.
785 (while cl-list2 776 (while cl-list2
786 (if (if (or cl-keys (numberp (car cl-list2))) 777 (if (if (or cl-keys (numberp (car cl-list2)))
787 (apply 'member* (cl-check-key (car cl-list2)) 778 (apply 'member* (cl-check-key (car cl-list2))
788 cl-list1 cl-keys) 779 cl-list1 cl-keys)
789 (memq (car cl-list2) cl-list1)) 780 (memq (car cl-list2) cl-list1))
790 (cl-push (car cl-list2) cl-res)) 781 (push (car cl-list2) cl-res))
791 (cl-pop cl-list2)) 782 (pop cl-list2))
792 cl-res))))) 783 cl-res)))))
793 784
794 (defun nintersection (cl-list1 cl-list2 &rest cl-keys) 785 (defun nintersection (cl-list1 cl-list2 &rest cl-keys)
795 "Combine LIST1 and LIST2 using a set-intersection operation. 786 "Combine LIST1 and LIST2 using a set-intersection operation.
796 The result list contains all items that appear in both LIST1 and LIST2. 787 The result list contains all items that appear in both LIST1 and LIST2.
811 (while cl-list1 802 (while cl-list1
812 (or (if (or cl-keys (numberp (car cl-list1))) 803 (or (if (or cl-keys (numberp (car cl-list1)))
813 (apply 'member* (cl-check-key (car cl-list1)) 804 (apply 'member* (cl-check-key (car cl-list1))
814 cl-list2 cl-keys) 805 cl-list2 cl-keys)
815 (memq (car cl-list1) cl-list2)) 806 (memq (car cl-list1) cl-list2))
816 (cl-push (car cl-list1) cl-res)) 807 (push (car cl-list1) cl-res))
817 (cl-pop cl-list1)) 808 (pop cl-list1))
818 cl-res)))) 809 cl-res))))
819 810
820 (defun nset-difference (cl-list1 cl-list2 &rest cl-keys) 811 (defun nset-difference (cl-list1 cl-list2 &rest cl-keys)
821 "Combine LIST1 and LIST2 using a set-difference operation. 812 "Combine LIST1 and LIST2 using a set-difference operation.
822 The result list contains all items that appear in LIST1 but not LIST2. 813 The result list contains all items that appear in LIST1 but not LIST2.
856 ((equal cl-list1 cl-list2) t) 847 ((equal cl-list1 cl-list2) t)
857 (t (cl-parsing-keywords (:key) (:test :test-not) 848 (t (cl-parsing-keywords (:key) (:test :test-not)
858 (while (and cl-list1 849 (while (and cl-list1
859 (apply 'member* (cl-check-key (car cl-list1)) 850 (apply 'member* (cl-check-key (car cl-list1))
860 cl-list2 cl-keys)) 851 cl-list2 cl-keys))
861 (cl-pop cl-list1)) 852 (pop cl-list1))
862 (null cl-list1))))) 853 (null cl-list1)))))
863 854
864 (defun subst-if (cl-new cl-pred cl-tree &rest cl-keys) 855 (defun subst-if (cl-new cl-pred cl-tree &rest cl-keys)
865 "Substitute NEW for elements matching PREDICATE in TREE (non-destructively). 856 "Substitute NEW for elements matching PREDICATE in TREE (non-destructively).
866 Return a copy of TREE with all matching elements replaced by NEW. 857 Return a copy of TREE with all matching elements replaced by NEW.
867 Keywords supported: :key" 858 Keywords supported: :key"
868 (apply 'sublis (list (cons nil cl-new)) cl-tree ':if cl-pred cl-keys)) 859 (apply 'sublis (list (cons nil cl-new)) cl-tree :if cl-pred cl-keys))
869 860
870 (defun subst-if-not (cl-new cl-pred cl-tree &rest cl-keys) 861 (defun subst-if-not (cl-new cl-pred cl-tree &rest cl-keys)
871 "Substitute NEW for elts not matching PREDICATE in TREE (non-destructively). 862 "Substitute NEW for elts not matching PREDICATE in TREE (non-destructively).
872 Return a copy of TREE with all non-matching elements replaced by NEW. 863 Return a copy of TREE with all non-matching elements replaced by NEW.
873 Keywords supported: :key" 864 Keywords supported: :key"
874 (apply 'sublis (list (cons nil cl-new)) cl-tree ':if-not cl-pred cl-keys)) 865 (apply 'sublis (list (cons nil cl-new)) cl-tree :if-not cl-pred cl-keys))
875 866
876 (defun nsubst (cl-new cl-old cl-tree &rest cl-keys) 867 (defun nsubst (cl-new cl-old cl-tree &rest cl-keys)
877 "Substitute NEW for OLD everywhere in TREE (destructively). 868 "Substitute NEW for OLD everywhere in TREE (destructively).
878 Any element of TREE which is `eql' to OLD is changed to NEW (via a call 869 Any element of TREE which is `eql' to OLD is changed to NEW (via a call
879 to `setcar'). 870 to `setcar').
882 873
883 (defun nsubst-if (cl-new cl-pred cl-tree &rest cl-keys) 874 (defun nsubst-if (cl-new cl-pred cl-tree &rest cl-keys)
884 "Substitute NEW for elements matching PREDICATE in TREE (destructively). 875 "Substitute NEW for elements matching PREDICATE in TREE (destructively).
885 Any element of TREE which matches is changed to NEW (via a call to `setcar'). 876 Any element of TREE which matches is changed to NEW (via a call to `setcar').
886 Keywords supported: :key" 877 Keywords supported: :key"
887 (apply 'nsublis (list (cons nil cl-new)) cl-tree ':if cl-pred cl-keys)) 878 (apply 'nsublis (list (cons nil cl-new)) cl-tree :if cl-pred cl-keys))
888 879
889 (defun nsubst-if-not (cl-new cl-pred cl-tree &rest cl-keys) 880 (defun nsubst-if-not (cl-new cl-pred cl-tree &rest cl-keys)
890 "Substitute NEW for elements not matching PREDICATE in TREE (destructively). 881 "Substitute NEW for elements not matching PREDICATE in TREE (destructively).
891 Any element of TREE which matches is changed to NEW (via a call to `setcar'). 882 Any element of TREE which matches is changed to NEW (via a call to `setcar').
892 Keywords supported: :key" 883 Keywords supported: :key"
893 (apply 'nsublis (list (cons nil cl-new)) cl-tree ':if-not cl-pred cl-keys)) 884 (apply 'nsublis (list (cons nil cl-new)) cl-tree :if-not cl-pred cl-keys))
894 885
895 (defun sublis (cl-alist cl-tree &rest cl-keys) 886 (defun sublis (cl-alist cl-tree &rest cl-keys)
896 "Perform substitutions indicated by ALIST in TREE (non-destructively). 887 "Perform substitutions indicated by ALIST in TREE (non-destructively).
897 Return a copy of TREE with all matching elements replaced. 888 Return a copy of TREE with all matching elements replaced.
898 Keywords supported: :test :test-not :key" 889 Keywords supported: :test :test-not :key"
950 (and (not (consp cl-x)) (not (consp cl-y)) (cl-check-match cl-x cl-y))) 941 (and (not (consp cl-x)) (not (consp cl-y)) (cl-check-match cl-x cl-y)))
951 942
952 943
953 (run-hooks 'cl-seq-load-hook) 944 (run-hooks 'cl-seq-load-hook)
954 945
946 ;;; arch-tag: ec1cc072-9006-4225-b6ba-d6b07ed1710c
955 ;;; cl-seq.el ends here 947 ;;; cl-seq.el ends here