Remove double indirection in array-fill!
authorDaniel Llorens <daniel.llorens@bluewin.ch>
Wed, 3 Apr 2013 20:40:40 +0000 (22:40 +0200)
committerLudovic Courtès <ludo@gnu.org>
Fri, 5 Apr 2013 20:54:14 +0000 (22:54 +0200)
* libguile/array-map.c: new function rafill, like scm_array_fill_int,
  but factors GVSET out of the loop. Use it in scm_array_fill_x instead of
  scm_array_fill_int.
* test-suite/tests/arrays.test: add test for array-fill! with stride != 1.

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
libguile/array-map.c
test-suite/tests/arrays.test

index b5b8cec..c86ea84 100644 (file)
@@ -318,6 +318,23 @@ scm_ramapc (void *cproc_ptr, SCM data, SCM ra0, SCM lra, const char *what)
     }
 }
 
+static int
+rafill (SCM dst, SCM fill)
+{
+  long n = (SCM_I_ARRAY_DIMS (dst)->ubnd - SCM_I_ARRAY_DIMS (dst)->lbnd + 1);
+  scm_t_array_handle h;
+  size_t i;
+  ssize_t inc;
+  scm_generalized_vector_get_handle (SCM_I_ARRAY_V (dst), &h);
+  i = h.base + h.dims[0].lbnd + SCM_I_ARRAY_BASE (dst)*h.dims[0].inc;
+  inc = SCM_I_ARRAY_DIMS (dst)->inc * h.dims[0].inc;
+
+  for (; n-- > 0; i += inc)
+    h.impl->vset (&h, i, fill);
+
+  scm_array_handle_release (&h);
+  return 1;
+}
 
 SCM_DEFINE (scm_array_fill_x, "array-fill!", 2, 0, 0,
            (SCM ra, SCM fill),
@@ -325,14 +342,14 @@ SCM_DEFINE (scm_array_fill_x, "array-fill!", 2, 0, 0,
            "returned is unspecified.")
 #define FUNC_NAME s_scm_array_fill_x
 {
-  scm_ramapc (scm_array_fill_int, fill, ra, SCM_EOL, FUNC_NAME);
+  scm_ramapc (rafill, fill, ra, SCM_EOL, FUNC_NAME);
   return SCM_UNSPECIFIED;
 }
 #undef FUNC_NAME
 
 /* to be used as cproc in scm_ramapc to fill an array dimension with
    "fill". */
-int 
+int
 scm_array_fill_int (SCM ra, SCM fill, SCM ignore SCM_UNUSED)
 #define FUNC_NAME s_scm_array_fill_x
 {
index aa97631..0b3d57c 100644 (file)
       (pass-if "0"      (array-fill! a 0)      #t)
       (pass-if "123"    (array-fill! a 123)    #t)
       (pass-if "-123"   (array-fill! a -123)   #t)
-      (pass-if "5/8"    (array-fill! a 5/8)    #t))))
+      (pass-if "5/8"    (array-fill! a 5/8)    #t)))
+
+  (with-test-prefix "noncompact"
+    (let* ((a (make-array 0 3 3))
+           (b (make-shared-array a (lambda (i) (list i i)) 3)))
+      (array-fill! b 9)
+      (pass-if
+        (and (equal? b #(9 9 9))
+             (equal? a #2((9 0 0) (0 9 0) (0 0 9))))))))
 
 ;;;
 ;;; array-copy!