2991413e9fa6

Add `across-flat-array` and `do-array`
[view raw] [browse files]
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