(defun make-array (dimensions &key
(element-type t)
(initial-element nil initial-element-p)
- initial-contents adjustable fill-pointer
+ (initial-contents nil initial-contents-p)
+ adjustable fill-pointer
displaced-to displaced-index-offset)
(let* ((dimensions (if (listp dimensions) dimensions (list dimensions)))
(array-rank (length (the list dimensions)))
(declare (type index length))
(when initial-element-p
(fill array initial-element))
- (when initial-contents
- (when initial-element
+ (when initial-contents-p
+ (when initial-element-p
(error "can't specify both :INITIAL-ELEMENT and ~
:INITIAL-CONTENTS"))
(unless (= length (length initial-contents))
(data (or displaced-to
(data-vector-from-inits
dimensions total-size element-type
- initial-contents initial-element initial-element-p)))
+ initial-contents initial-contents-p
+ initial-element initial-element-p)))
(array (make-array-header
(cond ((= array-rank 1)
(%complex-vector-widetag element-type))
(setf (%array-available-elements array) total-size)
(setf (%array-data-vector array) data)
(cond (displaced-to
- (when (or initial-element-p initial-contents)
+ (when (or initial-element-p initial-contents-p)
(error "Neither :INITIAL-ELEMENT nor :INITIAL-CONTENTS ~
can be specified along with :DISPLACED-TO"))
(let ((offset (or displaced-index-offset 0)))
;;; to FILL-DATA-VECTOR for error checking on the structure of
;;; initial-contents.
(defun data-vector-from-inits (dimensions total-size element-type
- initial-contents initial-element
- initial-element-p)
- (when (and initial-contents initial-element-p)
+ initial-contents initial-contents-p
+ initial-element initial-element-p)
+ (when (and initial-contents-p initial-element-p)
(error "cannot supply both :INITIAL-CONTENTS and :INITIAL-ELEMENT to
either MAKE-ARRAY or ADJUST-ARRAY."))
(let ((data (if initial-element-p
(error "~S cannot be used to initialize an array of type ~S."
initial-element element-type))
(fill (the vector data) initial-element)))
- (initial-contents
+ (initial-contents-p
(fill-data-vector data dimensions initial-contents)))
data))
(error "Axis number ~W is too big; ~S only has ~D dimension~:P."
axis-number array (%array-rank array)))
(t
- (%array-dimension array axis-number))))
+ ;; ANSI sayeth (ADJUST-ARRAY dictionary entry):
+ ;;
+ ;; "If A is displaced to B, the consequences are
+ ;; unspecified if B is adjusted in such a way that it no
+ ;; longer has enough elements to satisfy A.
+ ;;
+ ;; In situations where this matters we should be doing a
+ ;; bounds-check, which in turn uses ARRAY-DIMENSION -- so
+ ;; this seems like a good place to signal an error.
+ (multiple-value-bind (target offset) (array-displacement array)
+ (when (and target
+ (> (array-total-size array)
+ (- (array-total-size target) offset)))
+ (error 'displaced-to-array-too-small-error
+ :format-control "~@<The displaced-to array is too small. ~S ~
+ elements after offset required, ~S available.~:@>"
+ :format-arguments (list (array-total-size array)
+ (- (array-total-size target) offset))))
+ (%array-dimension array axis-number)))))
(defun array-dimensions (array)
#!+sb-doc
"Return T if (ADJUST-ARRAY ARRAY...) would return an array identical
to the argument, this happens for complex arrays."
(declare (array array))
+ ;; Note that this appears not to be a fundamental limitation.
+ ;; non-vector SIMPLE-ARRAYs are in fact capable of being adjusted,
+ ;; but in practice we test using ADJUSTABLE-ARRAY-P in ADJUST-ARRAY.
+ ;; -- CSR, 2004-03-01.
(not (typep array 'simple-array)))
\f
;;;; fill pointer frobbing stuff
(declare (fixnum fill-pointer))
(when (= fill-pointer (%array-available-elements vector))
(adjust-array vector (+ fill-pointer extension)))
- (setf (aref vector fill-pointer) new-element)
+ ;; disable bounds checking
+ (locally (declare (optimize (safety 0)))
+ (setf (aref vector fill-pointer) new-element))
(setf (%array-fill-pointer vector) (1+ fill-pointer))
fill-pointer))
(declare (fixnum fill-pointer))
(if (zerop fill-pointer)
(error "There is nothing left to pop.")
- (aref array
- (setf (%array-fill-pointer array)
- (1- fill-pointer))))))
+ ;; disable bounds checking (and any fixnum test)
+ (locally (declare (optimize (safety 0)))
+ (aref array
+ (setf (%array-fill-pointer array)
+ (1- fill-pointer)))))))
+
\f
;;;; ADJUST-ARRAY
(defun adjust-array (array dimensions &key
(element-type (array-element-type array))
(initial-element nil initial-element-p)
- initial-contents fill-pointer
+ (initial-contents nil initial-contents-p)
+ fill-pointer
displaced-to displaced-index-offset)
#!+sb-doc
"Adjust ARRAY's dimensions to the given DIMENSIONS and stuff."
element-type)))
(let ((array-rank (length (the list dimensions))))
(declare (fixnum array-rank))
- (when (and fill-pointer (> array-rank 1))
- (error "Multidimensional arrays can't have fill pointers."))
- (cond (initial-contents
+ (unless (= array-rank 1)
+ (when fill-pointer
+ (error "Only vectors can have fill pointers.")))
+ (cond (initial-contents-p
;; array former contents replaced by INITIAL-CONTENTS
(if (or initial-element-p displaced-to)
(error "INITIAL-CONTENTS may not be specified with ~
(let* ((array-size (apply #'* dimensions))
(array-data (data-vector-from-inits
dimensions array-size element-type
- initial-contents initial-element
- initial-element-p)))
+ initial-contents initial-contents-p
+ initial-element initial-element-p)))
(if (adjustable-array-p array)
(set-array-header array array-data array-size
(get-new-fill-pointer array array-size
(setf new-data
(data-vector-from-inits
dimensions new-length element-type
- initial-contents initial-element
- initial-element-p))
+ initial-contents initial-contents-p
+ initial-element initial-element-p))
(replace new-data old-data
:start2 old-start :end2 old-end))
(t (setf new-data
(> new-length old-length))
(data-vector-from-inits
dimensions new-length
- element-type () initial-element
- initial-element-p)
+ element-type () nil
+ initial-element initial-element-p)
old-data)))
(if (or (zerop old-length) (zerop new-length))
(when initial-element-p (fill new-data initial-element))
new-data dimensions new-length
element-type initial-element
initial-element-p))
- (set-array-header array new-data new-length
- new-length 0 dimensions nil)))))))))
+ (if (adjustable-array-p array)
+ (set-array-header array new-data new-length
+ new-length 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)))))))))))
+
(defun get-new-fill-pointer (old-array new-array-size fill-pointer)
(cond ((not fill-pointer)
(macrolet ((bump-index-list (index limits)
`(do ((subscripts ,index (cdr subscripts))
(limits ,limits (cdr limits)))
- ((null subscripts) nil)
+ ((null subscripts) :eof)
(cond ((< (the fixnum (car subscripts))
(the fixnum (car limits)))
(rplaca subscripts
(t (rplaca subscripts 0))))))
(do ((index (make-list (length old-dims) :initial-element 0)
(bump-index-list index limits)))
- ((null index))
+ ((eq index :eof))
(setf (aref new-data (row-major-index-from-dims index new-dims))
(aref old-data
(+ (the fixnum (row-major-index-from-dims index old-dims))
(defmacro def-bit-array-op (name function)
`(defun ,name (bit-array-1 bit-array-2 &optional result-bit-array)
+ #!+sb-doc
,(format nil
"Perform a bit-wise ~A on the elements of BIT-ARRAY-1 and ~
BIT-ARRAY-2,~% putting the results in RESULT-BIT-ARRAY. ~