# HG changeset patch # User Steve Losh # Date 1470874101 0 # Node ID 2991413e9fa6131f2e390d84e11cd52b2d55222d # Parent 4744b5c5d33dc3f435a693634d78a02715c33fb6 Add `across-flat-array` and `do-array` diff -r 4744b5c5d33d -r 2991413e9fa6 losh.lisp --- 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`. diff -r 4744b5c5d33d -r 2991413e9fa6 package.lisp --- 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