Add `across-flat-array` and `do-array`
author |
Steve Losh <steve@stevelosh.com> |
date |
Thu, 11 Aug 2016 00:08:21 +0000 |
parents |
4744b5c5d33d
|
children |
e14d7729f02a
|
branches/tags |
(none) |
files |
losh.lisp package.lisp |
Changes
--- a/losh.lisp Wed Aug 10 02:10:26 2016 +0000
+++ b/losh.lisp Thu Aug 11 00:08:21 2016 +0000
@@ -275,6 +275,35 @@
(for item :in list)
(collect item)))
+
+;;;; Arrays
+(defmacro do-array ((value array) &body body)
+ "Perform `body` once for each element in `array` using `value` for the place.
+
+ `array` can be multidimensional.
+
+ `value` will be `symbol-macrolet`ed to the appropriate `aref`, so you can use
+ it as a place if you want.
+
+ Returns the array.
+
+ Example:
+
+ (let ((arr (vector 1 2 3)))
+ (do-array (x arr)
+ (setf x (1+ x))))
+ => #(2 3 4)
+
+ "
+ (with-gensyms (i)
+ (once-only (array)
+ `(iterate (for ,i :index-of-flat-array ,array)
+ (symbol-macrolet ((,value (row-major-aref ,array ,i)))
+ ,@body)
+ (finally (return ,array))))))
+
+
+
;;;; Hash Tables
(defmacro gethash-or-init (key hash-table default-form)
"Get `key`'s value in `hash-table`, initializing if necessary.
@@ -448,6 +477,13 @@
(terminate))))))))
+(defclause-sequence ACROSS-FLAT-ARRAY INDEX-OF-FLAT-ARRAY
+ :access-fn 'row-major-aref
+ :size-fn 'array-total-size
+ :sequence-type 'array
+ :element-type t)
+
+
;;;; Distributions
(defun prefix-sums (list)
"Return a list of the prefix sums of the numbers in `list`.
--- a/package.lisp Wed Aug 10 02:10:26 2016 +0000
+++ b/package.lisp Thu Aug 11 00:08:21 2016 +0000
@@ -36,6 +36,8 @@
#:take
+ #:do-array
+
#:gethash-or-init
#:queue
@@ -58,6 +60,8 @@
#:in-lists
#:in-sequences
#:in-whatever
+ #:across-flat-array
+ #:index-of-flat-array
#:prefix-sums
#:frequencies