You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
3.3 KiB
92 lines
3.3 KiB
(in-package #:dynamic-array) |
|
|
|
(declaim (inline %make-array)) |
|
(defstruct (dynamic-array |
|
(:constructor %make-array) |
|
(:conc-name nil) |
|
(:predicate nil) |
|
(:copier nil)) |
|
(data (cl:make-array 0 :element-type t) :type simple-vector) |
|
(initial-element 0) |
|
(fill-pointer 0 :type fixnum)) |
|
|
|
(u:define-printer (dynamic-array stream :type nil) |
|
(format stream "~{~a~^ ~}" |
|
(coerce (subseq (data dynamic-array) 0 (fill-pointer dynamic-array)) 'list))) |
|
|
|
(defun make-array (&key (size 0) (capacity 128) (element-type t) |
|
initial-element) |
|
(assert (<= size capacity)) |
|
(let ((data (cl:make-array capacity :element-type element-type :initial-element initial-element))) |
|
(%make-array :data data :initial-element initial-element :fill-pointer size))) |
|
|
|
(u:fn-> copy (dynamic-array) dynamic-array) |
|
(defun copy (dynamic-array) |
|
(declare (optimize speed)) |
|
(%make-array :data (u:copy-array (data dynamic-array)) |
|
:initial-element (initial-element dynamic-array) |
|
:fill-pointer (fill-pointer dynamic-array))) |
|
|
|
(u:fn-> length (dynamic-array) fixnum) |
|
(declaim (inline length)) |
|
(defun length (dynamic-array) |
|
(fill-pointer dynamic-array)) |
|
|
|
(u:fn-> aref (dynamic-array fixnum) t) |
|
(declaim (inline aref)) |
|
(defun aref (dynamic-array index) |
|
(declare (optimize speed)) |
|
(if (< index (fill-pointer dynamic-array)) |
|
(locally (declare (optimize (safety 0))) |
|
(cl:aref (data dynamic-array) index)) |
|
(error "Index out of bounds."))) |
|
|
|
(u:fn-> (setf aref) (t dynamic-array fixnum) t) |
|
(declaim (inline (setf aref))) |
|
(defun (setf aref) (value dynamic-array index) |
|
(declare (optimize speed)) |
|
(if (< index (fill-pointer dynamic-array)) |
|
(locally (declare (optimize (safety 0))) |
|
(setf (cl:aref (data dynamic-array) index) value)) |
|
(error "Index out of bounds."))) |
|
|
|
(u:fn-> pop (dynamic-array &optional boolean) t) |
|
(declaim (inline pop)) |
|
(defun pop (dynamic-array &optional delete-p) |
|
(declare (optimize speed)) |
|
(let ((data (data dynamic-array)) |
|
(length (fill-pointer dynamic-array))) |
|
(unless (zerop length) |
|
(prog1 (cl:aref data (decf (fill-pointer dynamic-array))) |
|
(when delete-p |
|
(setf (cl:aref data (1- length)) nil)))))) |
|
|
|
(u:fn-> push (dynamic-array t) dynamic-array) |
|
(defun push (dynamic-array value) |
|
(declare (optimize speed)) |
|
(let* ((data (data dynamic-array)) |
|
(length (cl:length data)) |
|
(fill-pointer (fill-pointer dynamic-array))) |
|
(when (= fill-pointer length) |
|
(let ((data (adjust-array |
|
data |
|
(max 16 (min (* length 2) most-positive-fixnum)) |
|
:initial-element (initial-element dynamic-array)))) |
|
(setf (data dynamic-array) data))) |
|
(locally (declare (optimize (safety 0))) |
|
(setf (cl:aref (data dynamic-array) fill-pointer) value) |
|
(incf (fill-pointer dynamic-array))) |
|
dynamic-array)) |
|
|
|
(u:fn-> map (dynamic-array function) null) |
|
(defun map (dynamic-array func) |
|
(declare (optimize speed)) |
|
(loop :for i :below (length dynamic-array) |
|
:for element = (aref dynamic-array i) |
|
:do (funcall func element))) |
|
|
|
(u:fn-> find (dynamic-array t &key (:test function) (:key function)) t) |
|
(declaim (inline find)) |
|
(defun find (dynamic-array item &key (test #'eql) key) |
|
(declare (optimize speed)) |
|
(cl:find item (data dynamic-array) :key key :test test))
|
|
|