1.0.12.23: Optimize STRING-*-TRIM
[sbcl.git] / src / code / string.lisp
index 67579f7..dede948 100644 (file)
 
 ;;; %CHECK-VECTOR-SEQUENCE-BOUNDS is used to verify that the START and
 ;;; END arguments are valid bounding indices.
-;;;
-;;; FIXME: This causes a certain amount of double checking that could
-;;; be avoided, as if the string passes this (more stringent) test it
-;;; will automatically pass the tests in WITH-ARRAY-DATA.  Fixing this
-;;; would necessitate rearranging the transforms (maybe converting to
-;;; strings in the unasterisked versions and using this in the
-;;; transforms conditional on SAFETY>SPEED,SPACE).
 (defun %check-vector-sequence-bounds (vector start end)
   (%check-vector-sequence-bounds vector start end))
 
   `(let* ((,string (if (stringp ,string) ,string (string ,string))))
      (with-array-data ((,string ,string)
                        (,start ,start)
-                       (,end
-                        (%check-vector-sequence-bounds ,string ,start ,end)))
+                       (,end ,end)
+                       :check-fill-pointer t)
        ,@forms)))
 ;;; WITH-STRING is like WITH-ONE-STRING, but doesn't parse keywords.
 (sb!xc:defmacro with-string (string &rest forms)
   `(let ((,string (if (stringp ,string) ,string (string ,string))))
      (with-array-data ((,string ,string)
                        (start)
-                       (end (length (the vector ,string))))
+                       (end)
+                       :check-fill-pointer t)
        ,@forms)))
 ;;; WITH-TWO-STRINGS is used to set up string comparison operations. The
 ;;; keywords are parsed, and the strings are hacked into SIMPLE-STRINGs.
          (,string2 (if (stringp ,string2) ,string2 (string ,string2))))
      (with-array-data ((,string1 ,string1 :offset-var ,cum-offset-1)
                        (,start1 ,start1)
-                       (,end1 (%check-vector-sequence-bounds
-                               ,string1 ,start1 ,end1)))
+                       (,end1 ,end1)
+                       :check-fill-pointer t)
        (with-array-data ((,string2 ,string2)
                          (,start2 ,start2)
-                         (,end2 (%check-vector-sequence-bounds
-                                 ,string2 ,start2 ,end2)))
+                         (,end2 ,end2)
+                         :check-fill-pointer t)
          ,@forms))))
 ) ; EVAL-WHEN
 
@@ -410,36 +404,36 @@ new string COUNT long filled with the fill character."
   (%capitalize string start end))
 ) ; FLET
 
-(defun string-left-trim (char-bag string)
+(defun generic-string-trim (char-bag string left-p right-p)
   (with-string string
-    (do ((index start (1+ index)))
-        ((or (= index (the fixnum end))
-             (not (find (schar string index) char-bag :test #'char=)))
-         (subseq (the simple-string string) index end))
-      (declare (fixnum index)))))
+    (let* ((left-end (if left-p
+                         (do ((index start (1+ index)))
+                             ((or (= index (the fixnum end))
+                                  (not (find (schar string index)
+                                             char-bag
+                                             :test #'char=)))
+                              index)
+                           (declare (fixnum index)))
+                         0))
+           (right-end (if right-p
+                          (do ((index (1- (the fixnum end)) (1- index)))
+                              ((or (< index left-end)
+                                   (not (find (schar string index)
+                                              char-bag
+                                              :test #'char=)))
+                               (1+ index))
+                            (declare (fixnum index)))
+                          (length string))))
+      (if (and (eql left-end 0)
+               (eql right-end (length string)))
+          string
+          (subseq (the simple-string string) left-end right-end)))))
+
+(defun string-left-trim (char-bag string)
+  (generic-string-trim char-bag string t nil))
 
 (defun string-right-trim (char-bag string)
-  (with-string string
-    (do ((index (1- (the fixnum end)) (1- index)))
-        ((or (< index start)
-             (not (find (schar string index) char-bag :test #'char=)))
-         (subseq (the simple-string string) start (1+ index)))
-      (declare (fixnum index)))))
+  (generic-string-trim char-bag string nil t))
 
 (defun string-trim (char-bag string)
-  (with-string string
-    (let* ((left-end (do ((index start (1+ index)))
-                         ((or (= index (the fixnum end))
-                              (not (find (schar string index)
-                                         char-bag
-                                         :test #'char=)))
-                          index)
-                       (declare (fixnum index))))
-           (right-end (do ((index (1- (the fixnum end)) (1- index)))
-                          ((or (< index left-end)
-                               (not (find (schar string index)
-                                          char-bag
-                                          :test #'char=)))
-                           (1+ index))
-                        (declare (fixnum index)))))
-      (subseq (the simple-string string) left-end right-end))))
+  (generic-string-trim char-bag string t t))