1.0.23.22: rename SIMPLE-ARRAY-VECTOR to ARRAY-STORAGE-VECTOR
[sbcl.git] / src / code / array.lisp
index a7f1940..266c737 100644 (file)
@@ -768,31 +768,37 @@ of specialized arrays is supported."
   (declare (array array))
   (and (array-header-p array) (%array-fill-pointer-p array)))
 
+(defun fill-pointer-error (vector arg)
+  (cond (arg
+         (aver (array-has-fill-pointer-p vector))
+         (let ((max (%array-available-elements vector)))
+           (error 'simple-type-error
+                  :datum arg
+                  :expected-type (list 'integer 0 max)
+                  :format-control "The new fill pointer, ~S, is larger than the length of the vector (~S.)"
+                  :format-arguments (list arg max))))
+        (t
+         (error 'simple-type-error
+                :datum vector
+                :expected-type '(and vector (satisfies array-has-fill-pointer-p))
+                :format-control "~S is not an array with a fill pointer."
+                :format-arguments (list vector)))))
+
 (defun fill-pointer (vector)
   #!+sb-doc
   "Return the FILL-POINTER of the given VECTOR."
-  (declare (vector vector))
-  (if (and (array-header-p vector) (%array-fill-pointer-p vector))
+  (if (array-has-fill-pointer-p vector)
       (%array-fill-pointer vector)
-      (error 'simple-type-error
-             :datum vector
-             :expected-type '(and vector (satisfies array-has-fill-pointer-p))
-             :format-control "~S is not an array with a fill pointer."
-             :format-arguments (list vector))))
+      (fill-pointer-error vector nil)))
 
 (defun %set-fill-pointer (vector new)
-  (declare (vector vector) (fixnum new))
-  (if (and (array-header-p vector) (%array-fill-pointer-p vector))
-      (if (> new (%array-available-elements vector))
-        (error
-         "The new fill pointer, ~S, is larger than the length of the vector."
-         new)
-        (setf (%array-fill-pointer vector) new))
-      (error 'simple-type-error
-             :datum vector
-             :expected-type '(and vector (satisfies array-has-fill-pointer-p))
-             :format-control "~S is not an array with a fill pointer."
-             :format-arguments (list vector))))
+  (flet ((oops (x)
+           (fill-pointer-error vector x)))
+    (if (array-has-fill-pointer-p vector)
+        (if (> new (%array-available-elements vector))
+            (oops new)
+            (setf (%array-fill-pointer vector) new))
+        (oops nil))))
 
 ;;; FIXME: It'd probably make sense to use a MACROLET to share the
 ;;; guts of VECTOR-PUSH between VECTOR-PUSH-EXTEND. Such a macro
@@ -811,7 +817,8 @@ of specialized arrays is supported."
     (cond ((= fill-pointer (%array-available-elements array))
            nil)
           (t
-           (setf (aref array fill-pointer) new-el)
+           (locally (declare (optimize (safety 0)))
+             (setf (aref array fill-pointer) new-el))
            (setf (%array-fill-pointer array) (1+ fill-pointer))
            fill-pointer))))
 
@@ -972,12 +979,12 @@ of specialized arrays is supported."
                                        initial-element-p))
                    (if (adjustable-array-p array)
                        (set-array-header array new-data new-length
-                                         new-length 0 dimensions nil)
+                                         nil 0 dimensions nil)
                        (let ((new-array
                               (make-array-header
                                sb!vm:simple-array-widetag array-rank)))
                          (set-array-header new-array new-data new-length
-                                           new-length 0 dimensions nil)))))))))))
+                                           nil 0 dimensions nil)))))))))))
 
 
 (defun get-new-fill-pointer (old-array new-array-size fill-pointer)
@@ -1076,6 +1083,30 @@ of specialized arrays is supported."
       (setf (%array-dimension array 0) dimensions))
   (setf (%array-displaced-p array) displacedp)
   array)
+
+;;; User visible extension
+(declaim (ftype (function (array) (values (simple-array * (*)) &optional))
+                array-storage-vector))
+(defun array-storage-vector (array)
+  "Returns the underlying storage vector of ARRAY, which must be a non-displaced array.
+
+In SBCL, if ARRAY is a of type \(SIMPLE-ARRAY * \(*)), it is its own storage
+vector. Multidimensional arrays, arrays with fill pointers, and adjustable
+arrays have an underlying storage vector with the same ARRAY-ELEMENT-TYPE as
+ARRAY, which this function returns.
+
+Important note: the underlying vector is an implementation detail. Even though
+this function exposes it, changes in the implementation may cause this
+function to be removed without further warning."
+  ;; KLUDGE: Without TRULY-THE the system is not smart enough to figure out that
+  ;; the return value is always of the known type.
+  (truly-the (simple-array * (*))
+             (if (array-header-p array)
+                 (if (%array-displaced-p array)
+                     (error "~S cannot be used with displaced arrays. Use ~S instead."
+                            'array-storage-vector 'array-displacement)
+                     (%array-data-vector array))
+                 array)))
 \f
 ;;;; used by SORT