1 ;;;; (See the comments at the head of the file compiler-extras.lisp.)
5 (declaim (optimize (speed 3) (space 1)))
7 ;;; FIXME: should DEFUN REPLACE in terms of same expansion as
11 (cond ((and (typep seq1 'simple-vector)
12 (typep seq2 'simple-vector))
13 (%replace-vector-vector ..))
14 ((and (typep seq1 'simple-string)
15 (typep seq2 'simple-string))
16 (%replace-vector-vector ..))
20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21 ;;;; POSITION/FIND stuff
24 (eval-when (:compile-toplevel :load-toplevel :execute)
25 ;; FIXME: Report seq.impure.lisp test failures to cmucl-imp@cons.org.
26 ;; FIXME: Add BUGS entry for the way that inline expansions offunctions
27 ;; like FIND cause compiler warnings when the system can't prove that
28 ;; NIL is never returned; and give (NEED (FIND ..)) workaround.
29 (error "need to fix FIXMEs"))
31 ;;; logic to unravel :TEST, :TEST-NOT, and :KEY options in FIND,
33 (declaim (inline effective-find-position-test effective-find-position-key))
34 (defun effective-find-position-test (test test-not)
35 (cond ((and test test-not)
36 (error "can't specify both :TEST and :TEST-NOT"))
37 (test (%coerce-callable-to-function test))
39 ;; (Without DYNAMIC-EXTENT, this is potentially horribly
40 ;; inefficient, but since the TEST-NOT option is deprecated
41 ;; anyway, we don't care.)
42 (complement (%coerce-callable-to-function test-not)))
44 (defun effective-find-position-key (key)
46 (%coerce-callable-to-function key)
49 ;;; shared guts of out-of-line FIND, POSITION, FIND-IF, and POSITION-IF
50 (macrolet (;; shared logic for defining %FIND-POSITION and
51 ;; %FIND-POSITION-IF in terms of various inlineable cases
52 ;; of the expression defined in FROB and VECTOR*-FROB
54 `(etypecase sequence-arg
55 (list (frob sequence-arg from-end))
57 (with-array-data ((sequence sequence-arg :offset-var offset)
59 (end (or end (length sequence-arg))))
60 (multiple-value-bind (f p)
61 (macrolet ((frob2 () '(if from-end
63 (frob sequence nil))))
65 (simple-vector (frob2))
66 (simple-string (frob2))
67 (t (vector*-frob sequence))))
68 (declare (type (or index null) p))
69 (values f (and p (the index (+ p offset))))))))))
70 (defun %find-position (item sequence-arg from-end start end key test)
71 (macrolet ((frob (sequence from-end)
72 `(%find-position item ,sequence
73 ,from-end start end key test))
74 (vector*-frob (sequence)
75 `(%find-position-vector-macro item ,sequence
76 from-end start end key test)))
78 (defun %find-position-if (predicate sequence-arg from-end start end key)
79 (macrolet ((frob (sequence from-end)
80 `(%find-position-if predicate ,sequence
81 ,from-end start end key))
82 (vector*-frob (sequence)
83 `(%find-position-if-vector-macro predicate ,sequence
84 from-end start end key)))
87 ;;; the user interface to FIND and POSITION: Get all our ducks in a row,
88 ;;; then call %FIND-POSITION
89 (declaim (inline find position))
90 (macrolet ((def-find-position (fun-name values-index)
91 `(defun ,fun-name (item
107 (effective-find-position-key key)
108 (effective-find-position-test test
110 (def-find-position find 0)
111 (def-find-position position 1))
113 ;;; the user interface to FIND-IF and POSITION-IF, entirely analogous
114 ;;; to the interface to FIND and POSITION
115 (declaim (inline find-if position-if))
116 (macrolet ((def-find-position-if (fun-name values-index)
117 `(defun ,fun-name (predicate sequence
118 &key from-end (start 0) end key)
121 (%find-position-if (%coerce-callable-to-function predicate)
126 (effective-find-position-key key))))))
128 (def-find-position-if find-if 0)
129 (def-find-position-if position-if 1))
131 ;;; the deprecated functions FIND-IF-NOT and POSITION-IF-NOT
132 (macrolet ((def-find-position-if-not (fun-name values-index)
133 `(defun ,fun-name (predicate sequence
134 &key from-end (start 0) end key)
137 (%find-position-if (complement (%coerce-callable-to-function
143 (effective-find-position-key key))))))
144 (def-find-position-if-not find-if-not 0)
145 (def-find-position-if-not position-if-not 1))
146 ;;; FIXME: Remove uses of these deprecated functions, and of :TEST-NOT too.