fix arg order in sb-sequence:adjust-sequence
[sbcl.git] / src / pcl / sequence.lisp
blobb01aaa4acbf2e5fb2150e13d65256ff1fc1bd5b9
1 ;;;; Extensible sequences, based on the proposal by Christophe Rhodes.
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
6 ;;;; This software is in the public domain and is provided with
7 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
8 ;;;; more information.
10 (in-package "SB-IMPL")
12 ;;;; basic protocol
13 (define-condition sequence::protocol-unimplemented (type-error
14 reference-condition)
16 (:default-initargs
17 :references '((:sbcl :node "Extensible Sequences"))))
19 (defun sequence::protocol-unimplemented (sequence)
20 (error 'sequence::protocol-unimplemented
21 :datum sequence :expected-type '(or list vector)))
23 (defgeneric sequence:emptyp (sequence)
24 (:method ((s list)) (null s))
25 (:method ((s vector)) (zerop (length s)))
26 (:method ((s sequence)) (zerop (length s)))
27 #+sb-doc
28 (:documentation
29 "Returns T if SEQUENCE is an empty sequence and NIL
30 otherwise. Signals an error if SEQUENCE is not a sequence."))
32 (defgeneric sequence:length (sequence)
33 (:method ((s list)) (length s))
34 (:method ((s vector)) (length s))
35 (:method ((s sequence)) (sequence::protocol-unimplemented s))
36 #+sb-doc
37 (:documentation
38 "Returns the length of SEQUENCE or signals a PROTOCOL-UNIMPLEMENTED
39 error if the sequence protocol is not implemented for the class of
40 SEQUENCE."))
42 (defgeneric sequence:elt (sequence index)
43 (:method ((s list) index) (elt s index))
44 (:method ((s vector) index) (elt s index))
45 (:method ((s sequence) index) (sequence::protocol-unimplemented s))
46 #+sb-doc
47 (:documentation
48 "Returns the element at position INDEX of SEQUENCE or signals a
49 PROTOCOL-UNIMPLEMENTED error if the sequence protocol is not
50 implemented for the class of SEQUENCE."))
52 (defgeneric (setf sequence:elt) (new-value sequence index)
53 (:argument-precedence-order sequence new-value index)
54 (:method (new-value (s list) index) (setf (elt s index) new-value))
55 (:method (new-value (s vector) index) (setf (elt s index) new-value))
56 (:method (new-value (s sequence) index)
57 (sequence::protocol-unimplemented s))
58 #+sb-doc
59 (:documentation
60 "Replaces the element at position INDEX of SEQUENCE with NEW-VALUE
61 and returns NEW-VALUE or signals a PROTOCOL-UNIMPLEMENTED error if
62 the sequence protocol is not implemented for the class of
63 SEQUENCE."))
65 (defgeneric sequence:make-sequence-like
66 (sequence length &key initial-element initial-contents)
67 (:method ((s list) length &key
68 (initial-element nil iep) (initial-contents nil icp))
69 (cond
70 ((and icp iep) (error "bar"))
71 (iep (make-list length :initial-element initial-element))
72 (icp (unless (= (length initial-contents) length)
73 (error "foo"))
74 (let ((result (make-list length)))
75 (replace result initial-contents)
76 result))
77 (t (make-list length))))
78 (:method ((s vector) length &key
79 (initial-element nil iep) (initial-contents nil icp))
80 (cond
81 ((and icp iep) (error "foo"))
82 (iep (make-array length :element-type (array-element-type s)
83 :initial-element initial-element))
84 (icp (make-array length :element-type (array-element-type s)
85 :initial-contents initial-contents))
86 (t (make-array length :element-type (array-element-type s)))))
87 (:method ((s sequence) length &key initial-element initial-contents)
88 (declare (ignore initial-element initial-contents))
89 (sequence::protocol-unimplemented s))
90 #+sb-doc
91 (:documentation
92 "Returns a freshly allocated sequence of length LENGTH and of the
93 same class as SEQUENCE. Elements of the new sequence are
94 initialized to INITIAL-ELEMENT, if supplied, initialized to
95 INITIAL-CONTENTS if supplied, or identical to the elements of
96 SEQUENCE if neither is supplied. Signals a PROTOCOL-UNIMPLEMENTED
97 error if the sequence protocol is not implemented for the class of
98 SEQUENCE."))
100 (defgeneric sequence:adjust-sequence
101 (sequence length &key initial-element initial-contents)
102 (:method ((s list) length &key initial-element (initial-contents nil icp))
103 (if (eql length 0)
105 (let ((olength (length s)))
106 (cond
107 ((eql length olength) (if icp (replace s initial-contents) s))
108 ((< length olength)
109 (rplacd (nthcdr (1- length) s) nil)
110 (if icp (replace s initial-contents) s))
111 ((null s)
112 (let ((return (make-list length :initial-element initial-element)))
113 (if icp (replace return initial-contents) return)))
114 (t (rplacd (nthcdr (1- olength) s)
115 (make-list (- length olength)
116 :initial-element initial-element))
117 (if icp (replace s initial-contents) s))))))
118 (:method ((s vector) length &rest args &key (initial-contents nil icp) initial-element)
119 (declare (ignore initial-element))
120 (cond
121 ((and (array-has-fill-pointer-p s)
122 (>= (array-total-size s) length))
123 (setf (fill-pointer s) length)
124 (if icp (replace s initial-contents) s))
125 ((eql (length s) length)
126 (if icp (replace s initial-contents) s))
127 (t (apply #'adjust-array s length args))))
128 (:method ((s sequence) length &rest args)
129 (declare (ignore args))
130 (sequence::protocol-unimplemented s))
131 #+sb-doc
132 (:documentation
133 "Return destructively modified SEQUENCE or a freshly allocated
134 sequence of the same class as SEQUENCE of length LENGTH. Elements
135 of the returned sequence are initialized to INITIAL-ELEMENT, if
136 supplied, initialized to INITIAL-CONTENTS if supplied, or identical
137 to the elements of SEQUENCE if neither is supplied. Signals a
138 PROTOCOL-UNIMPLEMENTED error if the sequence protocol is not
139 implemented for the class of SEQUENCE."))
142 ;;;; iterator protocol
144 ;;; The general protocol
146 (defgeneric sequence:make-sequence-iterator (sequence &key from-end start end)
147 (:method ((s sequence) &key from-end (start 0) end)
148 (multiple-value-bind (iterator limit from-end)
149 (sequence:make-simple-sequence-iterator
150 s :from-end from-end :start start :end end)
151 (values iterator limit from-end
152 #'sequence:iterator-step #'sequence:iterator-endp
153 #'sequence:iterator-element #'(setf sequence:iterator-element)
154 #'sequence:iterator-index #'sequence:iterator-copy)))
155 (:method ((s t) &key from-end start end)
156 (declare (ignore from-end start end))
157 (error 'type-error
158 :datum s
159 :expected-type 'sequence))
160 #+sb-doc
161 (:documentation
162 "Returns a sequence iterator for SEQUENCE or, if START and/or END
163 are supplied, the subsequence bounded by START and END as nine
164 values:
166 1. iterator state
167 2. limit
168 3. from-end
169 4. step function
170 5. endp function
171 6. element function
172 7. setf element function
173 8. index function
174 9. copy state function
176 If FROM-END is NIL, the constructed iterator visits the specified
177 elements in the order in which they appear in SEQUENCE. Otherwise,
178 the elements are visited in the opposite order."))
180 ;;; the simple protocol: the simple iterator returns three values,
181 ;;; STATE, LIMIT and FROM-END.
183 ;;; magic termination value for list :from-end t
184 (defvar *exhausted* (cons nil nil))
186 (defgeneric sequence:make-simple-sequence-iterator
187 (sequence &key from-end start end)
188 (:method ((s list) &key from-end (start 0) end)
189 (if from-end
190 (let* ((termination (if (= start 0) *exhausted* (nthcdr (1- start) s)))
191 (init (if (<= (or end (length s)) start)
192 termination
193 (if end (last s (- (length s) (1- end))) (last s)))))
194 (values init termination t))
195 (cond
196 ((not end) (values (nthcdr start s) nil nil))
197 (t (let ((st (nthcdr start s)))
198 (values st (nthcdr (- end start) st) nil))))))
199 (:method ((s vector) &key from-end (start 0) end)
200 (let ((end (or end (length s))))
201 (if from-end
202 (values (1- end) (1- start) t)
203 (values start end nil))))
204 (:method ((s sequence) &key from-end (start 0) end)
205 (let ((end (or end (length s))))
206 (if from-end
207 (values (1- end) (1- start) from-end)
208 (values start end nil))))
209 #+sb-doc
210 (:documentation
211 "Returns a sequence iterator for SEQUENCE, START, END and FROM-END
212 as three values:
214 1. iterator state
215 2. limit
216 3. from-end
218 The returned iterator can be used with the generic iterator
219 functions ITERATOR-STEP, ITERATOR-ENDP, ITERATOR-ELEMENT, (SETF
220 ITERATOR-ELEMENT), ITERATOR-INDEX and ITERATOR-COPY."))
222 (defgeneric sequence:iterator-step (sequence iterator from-end)
223 (:method ((s list) iterator from-end)
224 (if from-end
225 (if (eq iterator s)
226 *exhausted*
227 (do* ((xs s (cdr xs)))
228 ((eq (cdr xs) iterator) xs)))
229 (cdr iterator)))
230 (:method ((s vector) iterator from-end)
231 (if from-end
232 (1- iterator)
233 (1+ iterator)))
234 (:method ((s sequence) iterator from-end)
235 (if from-end
236 (1- iterator)
237 (1+ iterator)))
238 #+sb-doc
239 (:documentation
240 "Moves ITERATOR one position forward or backward in SEQUENCE
241 depending on the iteration direction encoded in FROM-END."))
243 (defgeneric sequence:iterator-endp (sequence iterator limit from-end)
244 (:method ((s list) iterator limit from-end)
245 (eq iterator limit))
246 (:method ((s vector) iterator limit from-end)
247 (= iterator limit))
248 (:method ((s sequence) iterator limit from-end)
249 (= iterator limit))
250 #+sb-doc
251 (:documentation
252 "Returns non-NIL when ITERATOR has reached LIMIT (which may
253 correspond to the end of SEQUENCE) with respect to the iteration
254 direction encoded in FROM-END."))
256 (defgeneric sequence:iterator-element (sequence iterator)
257 (:method ((s list) iterator)
258 (car iterator))
259 (:method ((s vector) iterator)
260 (aref s iterator))
261 (:method ((s sequence) iterator)
262 (elt s iterator))
263 #+sb-doc
264 (:documentation
265 "Returns the element of SEQUENCE associated to the position of
266 ITERATOR."))
268 (defgeneric (setf sequence:iterator-element) (new-value sequence iterator)
269 (:method (o (s list) iterator)
270 (setf (car iterator) o))
271 (:method (o (s vector) iterator)
272 (setf (aref s iterator) o))
273 (:method (o (s sequence) iterator)
274 (setf (elt s iterator) o))
275 #+sb-doc
276 (:documentation
277 "Destructively modifies SEQUENCE by replacing the sequence element
278 associated to position of ITERATOR with NEW-VALUE."))
280 (defgeneric sequence:iterator-index (sequence iterator)
281 (:method ((s list) iterator)
282 ;; FIXME: this sucks. (In my defence, it is the equivalent of the
283 ;; Apple implementation in Dylan...)
284 (loop for l on s for i from 0 when (eq l iterator) return i))
285 (:method ((s vector) iterator) iterator)
286 (:method ((s sequence) iterator) iterator)
287 #+sb-doc
288 (:documentation
289 "Returns the position of ITERATOR in SEQUENCE."))
291 (defgeneric sequence:iterator-copy (sequence iterator)
292 (:method ((s list) iterator) iterator)
293 (:method ((s vector) iterator) iterator)
294 (:method ((s sequence) iterator) iterator)
295 #+sb-doc
296 (:documentation
297 "Returns a copy of ITERATOR which also traverses SEQUENCE but can
298 be mutated independently of ITERATOR."))
300 (defmacro sequence:with-sequence-iterator
301 ((&rest vars) (sequence &rest args &key from-end start end) &body body)
302 #+sb-doc
303 "Executes BODY with the elements of VARS bound to the iteration
304 state returned by MAKE-SEQUENCE-ITERATOR for SEQUENCE and
305 ARGS. Elements of VARS may be NIL in which case the corresponding
306 value returned by MAKE-SEQUENCE-ITERATOR is ignored."
307 (declare (ignore from-end start end))
308 (let* ((ignored '())
309 (vars (mapcar (lambda (x)
310 (or x (let ((name (gensym)))
311 (push name ignored)
312 name)))
313 vars)))
314 `(multiple-value-bind (,@vars) (sequence:make-sequence-iterator ,sequence ,@args)
315 (declare (type function ,@(nthcdr 3 vars))
316 (ignore ,@ignored))
317 ,@body)))
319 (defmacro sequence:with-sequence-iterator-functions
320 ((step endp elt setf index copy)
321 (sequence &rest args &key from-end start end)
322 &body body)
323 #+sb-doc
324 "Executes BODY with the names STEP, ENDP, ELT, SETF, INDEX and COPY
325 bound to local functions which execute the iteration state query and
326 mutation functions returned by MAKE-SEQUENCE-ITERATOR for SEQUENCE
327 and ARGS. STEP, ENDP, ELT, SETF, INDEX and COPY have dynamic
328 extent."
329 (declare (ignore from-end start end))
330 (let ((nstate (gensym "STATE")) (nlimit (gensym "LIMIT"))
331 (nfrom-end (gensym "FROM-END-")) (nstep (gensym "STEP"))
332 (nendp (gensym "ENDP")) (nelt (gensym "ELT"))
333 (nsetf (gensym "SETF")) (nindex (gensym "INDEX"))
334 (ncopy (gensym "COPY")))
335 `(sequence:with-sequence-iterator
336 (,nstate ,nlimit ,nfrom-end ,nstep ,nendp ,nelt ,nsetf ,nindex ,ncopy)
337 (,sequence,@args)
338 (flet ((,step () (setq ,nstate (funcall ,nstep ,sequence,nstate ,nfrom-end)))
339 (,endp () (funcall ,nendp ,sequence,nstate ,nlimit ,nfrom-end))
340 (,elt () (funcall ,nelt ,sequence,nstate))
341 (,setf (new-value) (funcall ,nsetf new-value ,sequence,nstate))
342 (,index () (funcall ,nindex ,sequence,nstate))
343 (,copy () (funcall ,ncopy ,sequence,nstate)))
344 (declare (truly-dynamic-extent #',step #',endp #',elt
345 #',setf #',index #',copy))
346 ,@body))))
348 (defun sequence:canonize-test (test test-not)
349 (cond
350 (test (if (functionp test) test (fdefinition test)))
351 (test-not (if (functionp test-not)
352 (complement test-not)
353 (complement (fdefinition test-not))))
354 (t #'eql)))
356 (defun sequence:canonize-key (key)
357 (or (and key (if (functionp key) key (fdefinition key))) #'identity))
359 ;;;; LOOP support. (DOSEQUENCE support is present in the core SBCL
360 ;;;; code).
361 (defun loop-elements-iteration-path (variable data-type prep-phrases)
362 (let (of-phrase)
363 (loop for (prep . rest) in prep-phrases do
364 (ecase prep
365 ((:of :in) (if of-phrase
366 (sb-loop::loop-error "Too many prepositions")
367 (setq of-phrase rest)))))
368 (destructuring-bind (it lim f-e step endp elt seq)
369 (loop repeat 7 collect (gensym))
370 (push `(let ((,seq ,(car of-phrase)))) sb-loop::*loop-wrappers*)
371 (push `(sequence:with-sequence-iterator (,it ,lim ,f-e ,step ,endp ,elt) (,seq))
372 sb-loop::*loop-wrappers*)
373 `(((,variable nil ,data-type)) () () nil (funcall ,endp ,seq ,it ,lim ,f-e)
374 (,variable (funcall ,elt ,seq ,it) ,it (funcall ,step ,seq ,it ,f-e))))))
375 (sb-loop::add-loop-path
376 '(element elements) 'loop-elements-iteration-path sb-loop::*loop-ansi-universe*
377 :preposition-groups '((:of :in)) :inclusive-permitted nil)
379 ;;;; generic implementations for sequence functions.
381 (defgeneric sequence:map (result-prototype function sequence &rest sequences)
382 #+sb-doc
383 (:documentation
384 "Implements CL:MAP for extended sequences.
386 RESULT-PROTOTYPE corresponds to the RESULT-TYPE of CL:MAP but
387 receives a prototype instance of an extended sequence class
388 instead of a type specifier. By dispatching on RESULT-PROTOTYPE,
389 methods on this generic function specify how extended sequence
390 classes act when they are specified as the result type in a CL:MAP
391 call. RESULT-PROTOTYPE may not be fully initialized and thus
392 should only be used for dispatch and to determine its class.
394 Another difference to CL:MAP is that FUNCTION is a function, not a
395 function designator."))
397 (defmethod sequence:map ((result-prototype sequence) (function function)
398 (sequence sequence) &rest sequences)
399 (let ((sequences (list* sequence sequences))
400 (min-length 0))
401 (declare (dynamic-extent sequences))
402 ;; Visit elements of SEQUENCES in parallel to determine length of
403 ;; the result. Determining the length of the result like this
404 ;; allows cases like
406 ;; (map 'my-sequence 'my-fun (circular-list 1 2 3) '(4 5 6))
408 ;; to return a sequence with three elements.
409 (flet ((counting-visit (&rest args)
410 (declare (truly-dynamic-extent args)
411 (ignore args))
412 (incf min-length)))
413 (declare (truly-dynamic-extent #'counting-visit))
414 (%map-for-effect #'counting-visit sequences))
415 ;; Map local function over SEQUENCES that steps through the result
416 ;; sequence and stores results of applying FUNCTION.
417 (binding* ((result (make-sequence (class-of result-prototype) min-length))
418 ((state nil from-end step nil nil setelt)
419 (sequence:make-sequence-iterator result)))
420 (declare (type function state step setelt))
421 (flet ((one-element (&rest args)
422 (declare (truly-dynamic-extent args))
423 (funcall setelt (apply function args) result state)
424 (setq state (funcall step result state from-end))))
425 (declare (truly-dynamic-extent #'one-element))
426 (%map-for-effect #'one-element sequences))
427 result)))
429 ;;; FIXME: COUNT, POSITION and FIND share an awful lot of structure.
430 ;;; They could usefully be defined in an OAOO way.
431 (defgeneric sequence:count
432 (item sequence &key from-end start end test test-not key)
433 (:argument-precedence-order sequence item))
434 (defmethod sequence:count
435 (item (sequence sequence) &key from-end (start 0) end test test-not key)
436 (let ((test (sequence:canonize-test test test-not))
437 (key (sequence:canonize-key key)))
438 (sequence:with-sequence-iterator (state limit from-end step endp elt)
439 (sequence :from-end from-end :start start :end end)
440 (do ((count 0))
441 ((funcall endp sequence state limit from-end) count)
442 (let ((o (funcall elt sequence state)))
443 (when (funcall test item (funcall key o))
444 (incf count))
445 (setq state (funcall step sequence state from-end)))))))
447 (defgeneric sequence:count-if (pred sequence &key from-end start end key)
448 (:argument-precedence-order sequence pred))
449 (defmethod sequence:count-if
450 (pred (sequence sequence) &key from-end (start 0) end key)
451 (let ((key (sequence:canonize-key key)))
452 (sequence:with-sequence-iterator (state limit from-end step endp elt)
453 (sequence :from-end from-end :start start :end end)
454 (do ((count 0))
455 ((funcall endp sequence state limit from-end) count)
456 (let ((o (funcall elt sequence state)))
457 (when (funcall pred (funcall key o))
458 (incf count))
459 (setq state (funcall step sequence state from-end)))))))
461 (defgeneric sequence:count-if-not (pred sequence &key from-end start end key)
462 (:argument-precedence-order sequence pred))
463 (defmethod sequence:count-if-not
464 (pred (sequence sequence) &key from-end (start 0) end key)
465 (let ((key (sequence:canonize-key key)))
466 (sequence:with-sequence-iterator (state limit from-end step endp elt)
467 (sequence :from-end from-end :start start :end end)
468 (do ((count 0))
469 ((funcall endp sequence state limit from-end) count)
470 (let ((o (funcall elt sequence state)))
471 (unless (funcall pred (funcall key o))
472 (incf count))
473 (setq state (funcall step sequence state from-end)))))))
475 (defgeneric sequence:find
476 (item sequence &key from-end start end test test-not key)
477 (:argument-precedence-order sequence item))
478 (defmethod sequence:find
479 (item (sequence sequence) &key from-end (start 0) end test test-not key)
480 (let ((test (sequence:canonize-test test test-not))
481 (key (sequence:canonize-key key)))
482 (sequence:with-sequence-iterator (state limit from-end step endp elt)
483 (sequence :from-end from-end :start start :end end)
484 (do ()
485 ((funcall endp sequence state limit from-end) nil)
486 (let ((o (funcall elt sequence state)))
487 (when (funcall test item (funcall key o))
488 (return o))
489 (setq state (funcall step sequence state from-end)))))))
491 (defgeneric sequence:find-if (pred sequence &key from-end start end key)
492 (:argument-precedence-order sequence pred))
493 (defmethod sequence:find-if
494 (pred (sequence sequence) &key from-end (start 0) end key)
495 (let ((key (sequence:canonize-key key)))
496 (sequence:with-sequence-iterator (state limit from-end step endp elt)
497 (sequence :from-end from-end :start start :end end)
498 (do ()
499 ((funcall endp sequence state limit from-end) nil)
500 (let ((o (funcall elt sequence state)))
501 (when (funcall pred (funcall key o))
502 (return o))
503 (setq state (funcall step sequence state from-end)))))))
505 (defgeneric sequence:find-if-not (pred sequence &key from-end start end key)
506 (:argument-precedence-order sequence pred))
507 (defmethod sequence:find-if-not
508 (pred (sequence sequence) &key from-end (start 0) end key)
509 (let ((key (sequence:canonize-key key)))
510 (sequence:with-sequence-iterator (state limit from-end step endp elt)
511 (sequence :from-end from-end :start start :end end)
512 (do ()
513 ((funcall endp sequence state limit from-end) nil)
514 (let ((o (funcall elt sequence state)))
515 (unless (funcall pred (funcall key o))
516 (return o))
517 (setq state (funcall step sequence state from-end)))))))
519 (defgeneric sequence:position
520 (item sequence &key from-end start end test test-not key)
521 (:argument-precedence-order sequence item))
522 (defmethod sequence:position
523 (item (sequence sequence) &key from-end (start 0) end test test-not key)
524 (let ((test (sequence:canonize-test test test-not))
525 (key (sequence:canonize-key key)))
526 (sequence:with-sequence-iterator (state limit from-end step endp elt)
527 (sequence :from-end from-end :start start :end end)
528 (do ((s (if from-end -1 1))
529 (pos (if from-end (1- (or end (length sequence))) start) (+ pos s)))
530 ((funcall endp sequence state limit from-end) nil)
531 (let ((o (funcall elt sequence state)))
532 (when (funcall test item (funcall key o))
533 (return pos))
534 (setq state (funcall step sequence state from-end)))))))
536 (defgeneric sequence:position-if (pred sequence &key from-end start end key)
537 (:argument-precedence-order sequence pred))
538 (defmethod sequence:position-if
539 (pred (sequence sequence) &key from-end (start 0) end key)
540 (let ((key (sequence:canonize-key key)))
541 (sequence:with-sequence-iterator (state limit from-end step endp elt)
542 (sequence :from-end from-end :start start :end end)
543 (do ((s (if from-end -1 1))
544 (pos (if from-end (1- (or end (length sequence))) start) (+ pos s)))
545 ((funcall endp sequence state limit from-end) nil)
546 (let ((o (funcall elt sequence state)))
547 (when (funcall pred (funcall key o))
548 (return pos))
549 (setq state (funcall step sequence state from-end)))))))
551 (defgeneric sequence:position-if-not
552 (pred sequence &key from-end start end key)
553 (:argument-precedence-order sequence pred))
554 (defmethod sequence:position-if-not
555 (pred (sequence sequence) &key from-end (start 0) end key)
556 (let ((key (sequence:canonize-key key)))
557 (sequence:with-sequence-iterator (state limit from-end step endp elt)
558 (sequence :from-end from-end :start start :end end)
559 (do ((s (if from-end -1 1))
560 (pos (if from-end (1- (or end (length sequence))) start) (+ pos s)))
561 ((funcall endp sequence state limit from-end) nil)
562 (let ((o (funcall elt sequence state)))
563 (unless (funcall pred (funcall key o))
564 (return pos))
565 (setq state (funcall step sequence state from-end)))))))
567 (defgeneric sequence:subseq (sequence start &optional end))
568 (defmethod sequence:subseq ((sequence sequence) start &optional end)
569 (let* ((end (or end (length sequence)))
570 (length (- end start))
571 (result (sequence:make-sequence-like sequence length)))
572 (sequence:with-sequence-iterator (state limit from-end step endp elt)
573 (sequence :start start :end end)
574 (declare (ignore limit endp))
575 (sequence:with-sequence-iterator (rstate rlimit rfrom-end rstep rendp relt rsetelt)
576 (result)
577 (declare (ignore rlimit rendp relt))
578 (do ((i 0 (+ i 1)))
579 ((>= i length) result)
580 (funcall rsetelt (funcall elt sequence state) result rstate)
581 (setq state (funcall step sequence state from-end))
582 (setq rstate (funcall rstep result rstate rfrom-end)))))))
584 (defgeneric sequence:copy-seq (sequence))
585 (defmethod sequence:copy-seq ((sequence sequence))
586 (sequence:subseq sequence 0))
588 (defgeneric sequence:fill (sequence item &key start end))
589 (defmethod sequence:fill ((sequence sequence) item &key (start 0) end)
590 (sequence:with-sequence-iterator (state limit from-end step endp elt setelt)
591 (sequence :start start :end end)
592 (declare (ignore elt))
593 (do ()
594 ((funcall endp sequence state limit from-end) sequence)
595 (funcall setelt item sequence state)
596 (setq state (funcall step sequence state from-end)))))
598 (defgeneric sequence:nsubstitute
599 (new old sequence &key start end from-end test test-not count key)
600 (:argument-precedence-order sequence new old))
601 (defmethod sequence:nsubstitute (new old (sequence sequence) &key (start 0)
602 end from-end test test-not count key)
603 (let ((test (sequence:canonize-test test test-not))
604 (key (sequence:canonize-key key)))
605 (sequence:with-sequence-iterator (state limit from-end step endp elt setelt)
606 (sequence :start start :end end :from-end from-end)
607 (do ((c 0))
608 ((or (and count (>= c count))
609 (funcall endp sequence state limit from-end))
610 sequence)
611 (when (funcall test old (funcall key (funcall elt sequence state)))
612 (incf c)
613 (funcall setelt new sequence state))
614 (setq state (funcall step sequence state from-end))))))
616 (defgeneric sequence:nsubstitute-if
617 (new predicate sequence &key start end from-end count key)
618 (:argument-precedence-order sequence new predicate))
619 (defmethod sequence:nsubstitute-if
620 (new predicate (sequence sequence) &key (start 0) end from-end count key)
621 (let ((key (sequence:canonize-key key)))
622 (sequence:with-sequence-iterator (state limit from-end step endp elt setelt)
623 (sequence :start start :end end :from-end from-end)
624 (do ((c 0))
625 ((or (and count (>= c count))
626 (funcall endp sequence state limit from-end))
627 sequence)
628 (when (funcall predicate (funcall key (funcall elt sequence state)))
629 (incf c)
630 (funcall setelt new sequence state))
631 (setq state (funcall step sequence state from-end))))))
633 (defgeneric sequence:nsubstitute-if-not
634 (new predicate sequence &key start end from-end count key)
635 (:argument-precedence-order sequence new predicate))
636 (defmethod sequence:nsubstitute-if-not
637 (new predicate (sequence sequence) &key (start 0) end from-end count key)
638 (let ((key (sequence:canonize-key key)))
639 (sequence:with-sequence-iterator (state limit from-end step endp elt setelt)
640 (sequence :start start :end end :from-end from-end)
641 (do ((c 0))
642 ((or (and count (>= c count))
643 (funcall endp sequence state limit from-end))
644 sequence)
645 (unless (funcall predicate (funcall key (funcall elt sequence state)))
646 (incf c)
647 (funcall setelt new sequence state))
648 (setq state (funcall step sequence state from-end))))))
650 (defgeneric sequence:substitute
651 (new old sequence &key start end from-end test test-not count key)
652 (:argument-precedence-order sequence new old))
653 (defmethod sequence:substitute (new old (sequence sequence) &rest args &key
654 (start 0) end from-end test test-not count key)
655 (declare (truly-dynamic-extent args))
656 (declare (ignore start end from-end test test-not count key))
657 (let ((result (copy-seq sequence)))
658 (apply #'sequence:nsubstitute new old result args)))
660 (defgeneric sequence:substitute-if
661 (new predicate sequence &key start end from-end count key)
662 (:argument-precedence-order sequence new predicate))
663 (defmethod sequence:substitute-if (new predicate (sequence sequence) &rest args
664 &key (start 0) end from-end count key)
665 (declare (truly-dynamic-extent args))
666 (declare (ignore start end from-end count key))
667 (let ((result (copy-seq sequence)))
668 (apply #'sequence:nsubstitute-if new predicate result args)))
670 (defgeneric sequence:substitute-if-not
671 (new predicate sequence &key start end from-end count key)
672 (:argument-precedence-order sequence new predicate))
673 (defmethod sequence:substitute-if-not
674 (new predicate (sequence sequence) &rest args &key
675 (start 0) end from-end count key)
676 (declare (truly-dynamic-extent args))
677 (declare (ignore start end from-end count key))
678 (let ((result (copy-seq sequence)))
679 (apply #'sequence:nsubstitute-if-not new predicate result args)))
681 (defun %sequence-replace (sequence1 sequence2 start1 end1 start2 end2)
682 (sequence:with-sequence-iterator (state1 limit1 from-end1 step1 endp1 elt1 setelt1)
683 (sequence1 :start start1 :end end1)
684 (declare (ignore elt1))
685 (sequence:with-sequence-iterator (state2 limit2 from-end2 step2 endp2 elt2)
686 (sequence2 :start start2 :end end2)
687 (do ()
688 ((or (funcall endp1 sequence1 state1 limit1 from-end1)
689 (funcall endp2 sequence2 state2 limit2 from-end2))
690 sequence1)
691 (funcall setelt1 (funcall elt2 sequence2 state2) sequence1 state1)
692 (setq state1 (funcall step1 sequence1 state1 from-end1))
693 (setq state2 (funcall step2 sequence2 state2 from-end2))))))
695 (defgeneric sequence:replace
696 (sequence1 sequence2 &key start1 end1 start2 end2)
697 (:argument-precedence-order sequence2 sequence1))
698 (defmethod sequence:replace
699 ((sequence1 sequence) (sequence2 sequence) &key
700 (start1 0) end1 (start2 0) end2)
701 (cond
702 ((eq sequence1 sequence2)
703 (let ((replaces (subseq sequence2 start2 end2)))
704 (%sequence-replace sequence1 replaces start1 end1 0 nil)))
705 (t (%sequence-replace sequence1 sequence2 start1 end1 start2 end2))))
707 (defgeneric sequence:nreverse (sequence))
708 (defmethod sequence:nreverse ((sequence sequence))
709 ;; FIXME: this, in particular the :from-end iterator, will suck
710 ;; mightily if the user defines a list-like structure.
711 (let ((length (length sequence)))
712 (sequence:with-sequence-iterator (state1 limit1 from-end1 step1 endp1 elt1 setelt1)
713 (sequence :end (floor length 2))
714 (sequence:with-sequence-iterator (state2 limit2 from-end2 step2 endp2 elt2 setelt2)
715 (sequence :start (ceiling length 2) :from-end t)
716 (declare (ignore limit2 endp2))
717 (do ()
718 ((funcall endp1 sequence state1 limit1 from-end1) sequence)
719 (let ((x (funcall elt1 sequence state1))
720 (y (funcall elt2 sequence state2)))
721 (funcall setelt1 y sequence state1)
722 (funcall setelt2 x sequence state2))
723 (setq state1 (funcall step1 sequence state1 from-end1))
724 (setq state2 (funcall step2 sequence state2 from-end2)))))))
726 (defgeneric sequence:reverse (sequence))
727 (defmethod sequence:reverse ((sequence sequence))
728 (let ((result (copy-seq sequence)))
729 (sequence:nreverse result)))
731 (defgeneric sequence:concatenate (result-prototype &rest sequences)
732 #+sb-doc
733 (:documentation
734 "Implements CL:CONCATENATE for extended sequences.
736 RESULT-PROTOTYPE corresponds to the RESULT-TYPE of CL:CONCATENATE
737 but receives a prototype instance of an extended sequence class
738 instead of a type specifier. By dispatching on RESULT-PROTOTYPE,
739 methods on this generic function specify how extended sequence
740 classes act when they are specified as the result type in a
741 CL:CONCATENATE call. RESULT-PROTOTYPE may not be fully initialized
742 and thus should only be used for dispatch and to determine its
743 class."))
745 (defmethod sequence:concatenate ((result-prototype sequence) &rest sequences)
746 (let* ((lengths (mapcar #'length sequences))
747 (result (sequence:make-sequence-like
748 result-prototype (reduce #'+ lengths))))
749 (loop with index = 0
750 for sequence in sequences
751 for length in lengths do
752 (replace result sequence :start1 index)
753 (incf index length))
754 result))
756 (defgeneric sequence:reduce
757 (function sequence &key from-end start end initial-value)
758 (:argument-precedence-order sequence function))
759 (defmethod sequence:reduce
760 (function (sequence sequence) &key from-end (start 0) end key
761 (initial-value nil ivp))
762 (let ((key (sequence:canonize-key key)))
763 (sequence:with-sequence-iterator (state limit from-end step endp elt)
764 (sequence :start start :end end :from-end from-end)
765 (if (funcall endp sequence state limit from-end)
766 (if ivp initial-value (funcall function))
767 (do* ((state state (funcall step sequence state from-end))
768 (value (cond
769 (ivp initial-value)
770 (t (prog1
771 (funcall key (funcall elt sequence state))
772 (setq state (funcall step sequence state from-end)))))))
773 ((funcall endp sequence state limit from-end) value)
774 (let ((e (funcall key (funcall elt sequence state))))
775 (if from-end
776 (setq value (funcall function e value))
777 (setq value (funcall function value e)))))))))
779 (defgeneric sequence:mismatch (sequence1 sequence2 &key from-end start1 end1
780 start2 end2 test test-not key))
781 (defmethod sequence:mismatch
782 ((sequence1 sequence) (sequence2 sequence) &key from-end (start1 0) end1
783 (start2 0) end2 test test-not key)
784 (let ((test (sequence:canonize-test test test-not))
785 (key (sequence:canonize-key key)))
786 (sequence:with-sequence-iterator (state1 limit1 from-end1 step1 endp1 elt1)
787 (sequence1 :start start1 :end end1 :from-end from-end)
788 (sequence:with-sequence-iterator (state2 limit2 from-end2 step2 endp2 elt2)
789 (sequence2 :start start2 :end end2 :from-end from-end)
790 (if from-end
791 (do ((result (or end1 (length sequence1)) (1- result))
792 (e1 (funcall endp1 sequence1 state1 limit1 from-end1)
793 (funcall endp1 sequence1 state1 limit1 from-end1))
794 (e2 (funcall endp2 sequence2 state2 limit2 from-end2)
795 (funcall endp2 sequence2 state2 limit2 from-end2)))
796 ((or e1 e2) (if (and e1 e2) nil result))
797 (let ((o1 (funcall key (funcall elt1 sequence1 state1)))
798 (o2 (funcall key (funcall elt2 sequence2 state2))))
799 (unless (funcall test o1 o2)
800 (return result))
801 (setq state1 (funcall step1 sequence1 state1 from-end1))
802 (setq state2 (funcall step2 sequence2 state2 from-end2))))
803 (do ((result start1 (1+ result))
804 (e1 (funcall endp1 sequence1 state1 limit1 from-end1)
805 (funcall endp1 sequence1 state1 limit1 from-end1))
806 (e2 (funcall endp2 sequence2 state2 limit2 from-end2)
807 (funcall endp2 sequence2 state2 limit2 from-end2)))
808 ((or e1 e2) (if (and e1 e2) nil result))
809 (let ((o1 (funcall key (funcall elt1 sequence1 state1)))
810 (o2 (funcall key (funcall elt2 sequence2 state2))))
811 (unless (funcall test o1 o2)
812 (return result)))
813 (setq state1 (funcall step1 sequence1 state1 from-end1))
814 (setq state2 (funcall step2 sequence2 state2 from-end2))))))))
816 (defgeneric sequence:search (sequence1 sequence2 &key from-end start1 end1
817 start2 end2 test test-not key))
818 (defmethod sequence:search
819 ((sequence1 sequence) (sequence2 sequence) &key from-end (start1 0) end1
820 (start2 0) end2 test test-not key)
821 (let* ((test (sequence:canonize-test test test-not))
822 (key (sequence:canonize-key key))
823 (range1 (- (or end1 (length sequence1)) start1))
824 (range2 (- (or end2 (length sequence2)) start2))
825 (count (1+ (- range2 range1))))
826 (when (minusp count)
827 (return-from sequence:search nil))
828 ;; Create an iteration state for SEQUENCE1 for the interesting
829 ;;range within SEQUENCE1. To compare this range against ranges in
830 ;;SEQUENCE2, we copy START-STATE1 and then mutate the copy.
831 (sequence:with-sequence-iterator (start-state1 nil from-end1 step1 nil elt1)
832 (sequence1 :start start1 :end end1 :from-end from-end)
833 ;; Create an iteration state for the interesting range within
834 ;; SEQUENCE2.
835 (sequence:with-sequence-iterator (start-state2 nil from-end2 step2 nil elt2 nil index2)
836 (sequence2 :start start2 :end end2 :from-end from-end)
837 ;; Copy both iterators at all COUNT possible match positions.
838 (dotimes (i count)
839 (let ((state1 (sequence:iterator-copy sequence1 start-state1))
840 (state2 (sequence:iterator-copy sequence2 start-state2)))
841 ;; Determine whether there is a match at the current
842 ;; position. Return immediately, if there is a match.
843 (dotimes
844 (j range1
845 (return-from sequence:search
846 (let ((position (funcall index2 sequence2 start-state2)))
847 (if from-end (- position range1 -1) position))))
848 (unless (funcall test
849 (funcall key (funcall elt1 sequence1 state1))
850 (funcall key (funcall elt2 sequence2 state2)))
851 (return nil))
852 (setq state1 (funcall step1 sequence1 state1 from-end1))
853 (setq state2 (funcall step2 sequence2 state2 from-end2))))
854 (setq start-state2 (funcall step2 sequence2 start-state2 from-end2)))))))
856 (defgeneric sequence:delete
857 (item sequence &key from-end test test-not start end count key)
858 (:argument-precedence-order sequence item))
859 (defmethod sequence:delete (item (sequence sequence) &key
860 from-end test test-not (start 0) end count key)
861 (let ((test (sequence:canonize-test test test-not))
862 (key (sequence:canonize-key key))
863 (c 0))
864 (sequence:with-sequence-iterator (state1 limit1 from-end1 step1 endp1 elt1 setelt1)
865 (sequence :start start :end end :from-end from-end)
866 (declare (ignore limit1 endp1 elt1))
867 (sequence:with-sequence-iterator (state2 limit2 from-end2 step2 endp2 elt2)
868 (sequence :start start :end end :from-end from-end)
869 (flet ((finish ()
870 (if from-end
871 (replace sequence sequence
872 :start1 start :end1 (- (length sequence) c)
873 :start2 (+ start c) :end2 (length sequence))
874 (unless (or (null end) (= end (length sequence)))
875 (replace sequence sequence :start2 end :start1 (- end c)
876 :end1 (- (length sequence) c))))
877 (sequence:adjust-sequence sequence (- (length sequence) c))))
878 (declare (truly-dynamic-extent #'finish))
879 (do ()
880 ((funcall endp2 sequence state2 limit2 from-end2) (finish))
881 (let ((e (funcall elt2 sequence state2)))
882 (loop
883 (when (and count (>= c count))
884 (return))
885 (if (funcall test item (funcall key e))
886 (progn
887 (incf c)
888 (setq state2 (funcall step2 sequence state2 from-end2))
889 (when (funcall endp2 sequence state2 limit2 from-end2)
890 (return-from sequence:delete (finish)))
891 (setq e (funcall elt2 sequence state2)))
892 (return)))
893 (funcall setelt1 e sequence state1))
894 (setq state1 (funcall step1 sequence state1 from-end1))
895 (setq state2 (funcall step2 sequence state2 from-end2))))))))
897 (defgeneric sequence:delete-if
898 (predicate sequence &key from-end start end count key)
899 (:argument-precedence-order sequence predicate))
900 (defmethod sequence:delete-if (predicate (sequence sequence) &key
901 from-end (start 0) end count key)
902 (let ((key (sequence:canonize-key key))
903 (c 0))
904 (sequence:with-sequence-iterator (state1 limit1 from-end1 step1 endp1 elt1 setelt1)
905 (sequence :start start :end end :from-end from-end)
906 (declare (ignore limit1 endp1 elt1))
907 (sequence:with-sequence-iterator (state2 limit2 from-end2 step2 endp2 elt2)
908 (sequence :start start :end end :from-end from-end)
909 (flet ((finish ()
910 (if from-end
911 (replace sequence sequence
912 :start1 start :end1 (- (length sequence) c)
913 :start2 (+ start c) :end2 (length sequence))
914 (unless (or (null end) (= end (length sequence)))
915 (replace sequence sequence :start2 end :start1 (- end c)
916 :end1 (- (length sequence) c))))
917 (sequence:adjust-sequence sequence (- (length sequence) c))))
918 (declare (truly-dynamic-extent #'finish))
919 (do ()
920 ((funcall endp2 sequence state2 limit2 from-end2) (finish))
921 (let ((e (funcall elt2 sequence state2)))
922 (loop
923 (when (and count (>= c count))
924 (return))
925 (if (funcall predicate (funcall key e))
926 (progn
927 (incf c)
928 (setq state2 (funcall step2 sequence state2 from-end2))
929 (when (funcall endp2 sequence state2 limit2 from-end2)
930 (return-from sequence:delete-if (finish)))
931 (setq e (funcall elt2 sequence state2)))
932 (return)))
933 (funcall setelt1 e sequence state1))
934 (setq state1 (funcall step1 sequence state1 from-end1))
935 (setq state2 (funcall step2 sequence state2 from-end2))))))))
937 (defgeneric sequence:delete-if-not
938 (predicate sequence &key from-end start end count key)
939 (:argument-precedence-order sequence predicate))
940 (defmethod sequence:delete-if-not (predicate (sequence sequence) &key
941 from-end (start 0) end count key)
942 (let ((key (sequence:canonize-key key))
943 (c 0))
944 (sequence:with-sequence-iterator (state1 limit1 from-end1 step1 endp1 elt1 setelt1)
945 (sequence :start start :end end :from-end from-end)
946 (declare (ignore limit1 endp1 elt1))
947 (sequence:with-sequence-iterator (state2 limit2 from-end2 step2 endp2 elt2)
948 (sequence :start start :end end :from-end from-end)
949 (flet ((finish ()
950 (if from-end
951 (replace sequence sequence
952 :start1 start :end1 (- (length sequence) c)
953 :start2 (+ start c) :end2 (length sequence))
954 (unless (or (null end) (= end (length sequence)))
955 (replace sequence sequence :start2 end :start1 (- end c)
956 :end1 (- (length sequence) c))))
957 (sequence:adjust-sequence sequence (- (length sequence) c))))
958 (declare (truly-dynamic-extent #'finish))
959 (do ()
960 ((funcall endp2 sequence state2 limit2 from-end2) (finish))
961 (let ((e (funcall elt2 sequence state2)))
962 (loop
963 (when (and count (>= c count))
964 (return))
965 (if (funcall predicate (funcall key e))
966 (return)
967 (progn
968 (incf c)
969 (setq state2 (funcall step2 sequence state2 from-end2))
970 (when (funcall endp2 sequence state2 limit2 from-end2)
971 (return-from sequence:delete-if-not (finish)))
972 (setq e (funcall elt2 sequence state2)))))
973 (funcall setelt1 e sequence state1))
974 (setq state1 (funcall step1 sequence state1 from-end1))
975 (setq state2 (funcall step2 sequence state2 from-end2))))))))
977 (defgeneric sequence:remove
978 (item sequence &key from-end test test-not start end count key)
979 (:argument-precedence-order sequence item))
980 (defmethod sequence:remove (item (sequence sequence) &rest args &key
981 from-end test test-not (start 0) end count key)
982 (declare (truly-dynamic-extent args))
983 (declare (ignore from-end test test-not start end count key))
984 (let ((result (copy-seq sequence)))
985 (apply #'sequence:delete item result args)))
987 (defgeneric sequence:remove-if
988 (predicate sequence &key from-end start end count key)
989 (:argument-precedence-order sequence predicate))
990 (defmethod sequence:remove-if (predicate (sequence sequence) &rest args &key
991 from-end (start 0) end count key)
992 (declare (truly-dynamic-extent args))
993 (declare (ignore from-end start end count key))
994 (let ((result (copy-seq sequence)))
995 (apply #'sequence:delete-if predicate result args)))
997 (defgeneric sequence:remove-if-not
998 (predicate sequence &key from-end start end count key)
999 (:argument-precedence-order sequence predicate))
1000 (defmethod sequence:remove-if-not (predicate (sequence sequence) &rest args
1001 &key from-end (start 0) end count key)
1002 (declare (truly-dynamic-extent args))
1003 (declare (ignore from-end start end count key))
1004 (let ((result (copy-seq sequence)))
1005 (apply #'sequence:delete-if-not predicate result args)))
1007 (defgeneric sequence:delete-duplicates
1008 (sequence &key from-end test test-not start end key))
1009 (defmethod sequence:delete-duplicates
1010 ((sequence sequence) &key from-end test test-not (start 0) end key)
1011 (let ((test (sequence:canonize-test test test-not))
1012 (key (sequence:canonize-key key))
1013 (c 0))
1014 (sequence:with-sequence-iterator (state1 limit1 from-end1 step1 endp1 elt1 setelt1)
1015 (sequence :start start :end end :from-end from-end)
1016 (declare (ignore limit1 endp1 elt1))
1017 (sequence:with-sequence-iterator (state2 limit2 from-end2 step2 endp2 elt2)
1018 (sequence :start start :end end :from-end from-end)
1019 (flet ((finish ()
1020 (if from-end
1021 (replace sequence sequence
1022 :start1 start :end1 (- (length sequence) c)
1023 :start2 (+ start c) :end2 (length sequence))
1024 (unless (or (null end) (= end (length sequence)))
1025 (replace sequence sequence :start2 end :start1 (- end c)
1026 :end1 (- (length sequence) c))))
1027 (sequence:adjust-sequence sequence (- (length sequence) c))))
1028 (declare (truly-dynamic-extent #'finish))
1029 (do ((end (or end (length sequence)))
1030 (step 0 (1+ step)))
1031 ((funcall endp2 sequence state2 limit2 from-end2) (finish))
1032 (let ((e (funcall elt2 sequence state2)))
1033 (loop
1034 ;; FIXME: replace with POSITION once position is
1035 ;; working
1036 (if (> (count (funcall key e) sequence :test test :key key
1037 :start (if from-end start (+ start step 1))
1038 :end (if from-end (- end step 1) end))
1040 (progn
1041 (incf c)
1042 (incf step)
1043 (setq state2 (funcall step2 sequence state2 from-end2))
1044 (when (funcall endp2 sequence state2 limit2 from-end2)
1045 (return-from sequence:delete-duplicates (finish)))
1046 (setq e (funcall elt2 sequence state2)))
1047 (progn
1048 (return))))
1049 (funcall setelt1 e sequence state1))
1050 (setq state1 (funcall step1 sequence state1 from-end1))
1051 (setq state2 (funcall step2 sequence state2 from-end2))))))))
1053 (defgeneric sequence:remove-duplicates
1054 (sequence &key from-end test test-not start end key))
1055 (defmethod sequence:remove-duplicates
1056 ((sequence sequence) &rest args &key from-end test test-not (start 0) end key)
1057 (declare (truly-dynamic-extent args))
1058 (declare (ignore from-end test test-not start end key))
1059 (let ((result (copy-seq sequence)))
1060 (apply #'sequence:delete-duplicates result args)))
1062 (defgeneric sequence:sort (sequence predicate &key key))
1063 (defmethod sequence:sort ((sequence sequence) predicate &rest args &key key)
1064 (declare (truly-dynamic-extent args))
1065 (declare (ignore key))
1066 (let* ((length (length sequence))
1067 (vector (make-array length)))
1068 (sequence:with-sequence-iterator (state limit from-end step endp elt)
1069 (sequence)
1070 (declare (ignore limit endp))
1071 (do ((i 0 (1+ i)))
1072 ((>= i length))
1073 (setf (aref vector i) (funcall elt sequence state))
1074 (setq state (funcall step sequence state from-end))))
1075 (apply #'sort vector predicate args)
1076 (sequence:with-sequence-iterator (state limit from-end step endp elt setelt)
1077 (sequence)
1078 (declare (ignore limit endp elt))
1079 (do ((i 0 (1+ i)))
1080 ((>= i length) sequence)
1081 (funcall setelt (aref vector i) sequence state)
1082 (setq state (funcall step sequence state from-end))))))
1084 (defgeneric sequence:stable-sort (sequence predicate &key key))
1085 (defmethod sequence:stable-sort
1086 ((sequence sequence) predicate &rest args &key key)
1087 (declare (truly-dynamic-extent args))
1088 (declare (ignore key))
1089 (let* ((length (length sequence))
1090 (vector (make-array length)))
1091 (sequence:with-sequence-iterator (state limit from-end step endp elt)
1092 (sequence)
1093 (declare (ignore limit endp))
1094 (do ((i 0 (1+ i)))
1095 ((>= i length))
1096 (setf (aref vector i) (funcall elt sequence state))
1097 (setq state (funcall step sequence state from-end))))
1098 (apply #'stable-sort vector predicate args)
1099 (sequence:with-sequence-iterator (state limit from-end step endp elt setelt)
1100 (sequence)
1101 (declare (ignore limit endp elt))
1102 (do ((i 0 (1+ i)))
1103 ((>= i length) sequence)
1104 (funcall setelt (aref vector i) sequence state)
1105 (setq state (funcall step sequence state from-end))))))
1107 (defgeneric sequence:merge (result-prototype sequence1 sequence2 predicate &key key)
1108 #+sb-doc
1109 (:documentation
1110 "Implements CL:MERGE for extended sequences.
1112 RESULT-PROTOTYPE corresponds to the RESULT-TYPE of CL:MERGE but
1113 receives a prototype instance of an extended sequence class
1114 instead of a type specifier. By dispatching on RESULT-PROTOTYPE,
1115 methods on this generic function specify how extended sequence
1116 classes act when they are specified as the result type in a
1117 CL:MERGE call. RESULT-PROTOTYPE may not be fully initialized and
1118 thus should only be used for dispatch and to determine its class.
1120 Another difference to CL:MERGE is that PREDICATE is a function,
1121 not a function designator."))
1123 (defmethod sequence:merge ((result-prototype sequence)
1124 (sequence1 sequence) (sequence2 sequence)
1125 (predicate function) &key key)
1126 (let ((key-function (when key
1127 (%coerce-callable-to-fun key)))
1128 (result (sequence:make-sequence-like
1129 result-prototype (+ (length sequence1) (length sequence2))))
1130 endp1 elt1 key1 endp2 elt2 key2)
1131 (sequence:with-sequence-iterator-functions
1132 (step-result endp-result elt-result setelt-result index-result copy-result) (result) ; TODO allow nil and fewer number of elements
1133 (declare (ignorable #'endp-result #'elt-result #'copy-result))
1134 (sequence:with-sequence-iterator-functions
1135 (step1 endp1 elt1 setelt1 index1 copy1) (sequence1)
1136 (declare (ignorable #'setelt1 #'copy1))
1137 (sequence:with-sequence-iterator-functions
1138 (step2 endp2 elt2 setelt2 index2 copy2) (sequence2)
1139 (declare (ignorable #'setelt2 #'copy2))
1140 (labels ((pop/no-key1 ()
1141 (unless (setf endp1 (endp1))
1142 (setf elt1 (elt1))))
1143 (pop/no-key2 ()
1144 (unless (setf endp2 (endp2))
1145 (setf elt2 (elt2))))
1146 (pop/key1 ()
1147 (unless (setf endp1 (endp1))
1148 (setf key1 (funcall (truly-the function key-function)
1149 (setf elt1 (elt1))))))
1150 (pop/key2 ()
1151 (unless (setf endp2 (endp2))
1152 (setf key2 (funcall (truly-the function key-function)
1153 (setf elt2 (elt2))))))
1154 (pop-one/no-key ()
1155 (if (funcall predicate elt2 elt1) ; see comment in MERGE-LIST*
1156 (prog1 elt2 (step2) (pop/no-key2))
1157 (prog1 elt1 (step1) (pop/no-key1))))
1158 (pop-one/key ()
1159 (if (funcall predicate key2 key1)
1160 (prog1 elt2 (step2) (pop/key2))
1161 (prog1 elt1 (step1) (pop/key1)))))
1162 (declare (truly-dynamic-extent #'pop/no-key1 #'pop/no-key2
1163 #'pop/key1 #'pop/key2
1164 #'pop-one/no-key #'pop-one/key))
1165 ;; Populate ENDP{1,2}, ELT{1,2} and maybe KEY{1,2}.
1166 (cond (key-function (pop/key1) (pop/key2))
1167 (t (pop/no-key1) (pop/no-key2)))
1168 (loop with pop-one = (if key-function #'pop-one/key #'pop-one/no-key) do
1169 (cond
1170 (endp2 ; batch-replace rest of SEQUENCE1 if SEQUENCE2 exhausted
1171 (unless endp1
1172 (replace result sequence1 :start1 (index-result) :start2 (index1)))
1173 (return))
1174 (endp1
1175 (unless endp2
1176 (replace result sequence2 :start1 (index-result) :start2 (index2)))
1177 (return))
1179 (setelt-result (funcall pop-one))
1180 (step-result))))))))
1181 result))