(end end)
:force-inline t
:check-fill-pointer t)
- (macrolet ((frob ()
- `(locally (declare (optimize (safety 0) (speed 3)))
- (do ((i start (1+ i)))
- ((= i end) sequence)
- (declare (index i))
- (setf (aref data i) item)))))
- (etypecase data
- #!+sb-unicode
- ((simple-array character (*))
- (let ((item (locally (declare (optimize (safety 3)))
- (the character item))))
- (frob)))
- ((simple-array base-char (*))
- (let ((item (locally (declare (optimize (safety 3)))
- (the base-char item))))
- (frob)))))))
+ ;; DEFTRANSFORM for FILL will turn these into
+ ;; calls to UB*-BASH-FILL.
+ (etypecase data
+ #!+sb-unicode
+ ((simple-array character (*))
+ (let ((item (locally (declare (optimize (safety 3)))
+ (the character item))))
+ (fill data item :start start :end end)))
+ ((simple-array base-char (*))
+ (let ((item (locally (declare (optimize (safety 3)))
+ (the base-char item))))
+ (fill data item :start start :end end))))))
(defun fill (sequence item &key (start 0) end)
#!+sb-doc
(t
(bad-sequence-type-error output-type-spec)))))
+;;; Efficient out-of-line concatenate for strings. Compiler transforms
+;;; CONCATENATE 'STRING &co into these.
+(macrolet ((def (name element-type)
+ `(defun ,name (&rest sequences)
+ (declare (dynamic-extent sequences)
+ (optimize speed))
+ (let* ((lengths (mapcar #'length sequences))
+ (result (make-array (the integer (apply #'+ lengths))
+ :element-type ',element-type))
+ (start 0))
+ (declare (index start))
+ (dolist (seq sequences)
+ (string-dispatch
+ ((simple-array character (*))
+ (simple-array base-char (*))
+ t)
+ seq
+ (replace result seq :start1 start))
+ (incf start (the index (pop lengths))))
+ result))))
+ (def %concatenate-to-string character)
+ (def %concatenate-to-base-string base-char))
+
;;; internal frobs
;;; FIXME: These are weird. They're never called anywhere except in
;;; CONCATENATE. It seems to me that the macros ought to just