Optimize 'string-hash'.
[bpt/guile.git] / libguile / generalized-arrays.c
index ff05151..59925a0 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995,1996,1997,1998,2000,2001,2002,2003,2004, 2005, 2006, 2009, 2010 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1996,1997,1998,2000,2001,2002,2003,2004, 2005, 2006, 2009, 2010, 2013 Free Software Foundation, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
 #include "libguile/generalized-arrays.h"
 
 
+SCM_INTERNAL SCM scm_i_array_ref (SCM v,
+                                  SCM idx0, SCM idx1, SCM idxN);
+SCM_INTERNAL SCM scm_i_array_set_x (SCM v, SCM obj,
+                                    SCM idx0, SCM idx1, SCM idxN);
+
+
 int
 scm_is_array (SCM obj)
 {
@@ -107,6 +113,35 @@ SCM_DEFINE (scm_array_rank, "array-rank", 1, 0, 0,
 #undef FUNC_NAME
 
 
+size_t
+scm_c_array_length (SCM array)
+{
+  scm_t_array_handle handle;
+  size_t res;
+
+  scm_array_get_handle (array, &handle);
+  if (scm_array_handle_rank (&handle) < 1)
+    {
+      scm_array_handle_release (&handle);
+      scm_wrong_type_arg_msg (NULL, 0, array, "array of nonzero rank");
+    }
+  res = handle.dims[0].ubnd - handle.dims[0].lbnd + 1;
+  scm_array_handle_release (&handle);
+
+  return res;
+}
+
+SCM_DEFINE (scm_array_length, "array-length", 1, 0, 0, 
+           (SCM array),
+           "Return the length of an array: its first dimension.\n"
+            "It is an error to ask for the length of an array of rank 0.")
+#define FUNC_NAME s_scm_array_length
+{
+  return scm_from_size_t (scm_c_array_length (array));
+}
+#undef FUNC_NAME
+
+
 SCM_DEFINE (scm_array_dimensions, "array-dimensions", 1, 0, 0, 
            (SCM ra),
            "@code{array-dimensions} is similar to @code{array-shape} but replaces\n"
@@ -195,11 +230,35 @@ SCM_DEFINE (scm_array_in_bounds_p, "array-in-bounds?", 1, 0, 1,
 }
 #undef FUNC_NAME
 
-SCM_DEFINE (scm_array_ref, "array-ref", 1, 0, 1,
-           (SCM v, SCM args),
-           "Return the element at the @code{(index1, index2)} element in\n"
-           "@var{array}.")
-#define FUNC_NAME s_scm_array_ref
+
+SCM
+scm_c_array_ref_1 (SCM array, ssize_t idx0)
+{
+  scm_t_array_handle handle;
+  SCM res;
+
+  scm_array_get_handle (array, &handle);
+  res = scm_array_handle_ref (&handle, scm_array_handle_pos_1 (&handle, idx0));
+  scm_array_handle_release (&handle);
+  return res;
+}
+
+
+SCM
+scm_c_array_ref_2 (SCM array, ssize_t idx0, ssize_t idx1)
+{
+  scm_t_array_handle handle;
+  SCM res;
+
+  scm_array_get_handle (array, &handle);
+  res = scm_array_handle_ref (&handle, scm_array_handle_pos_2 (&handle, idx0, idx1));
+  scm_array_handle_release (&handle);
+  return res;
+}
+
+
+SCM
+scm_array_ref (SCM v, SCM args)
 {
   scm_t_array_handle handle;
   SCM res;
@@ -209,14 +268,34 @@ SCM_DEFINE (scm_array_ref, "array-ref", 1, 0, 1,
   scm_array_handle_release (&handle);
   return res;
 }
-#undef FUNC_NAME
 
 
-SCM_DEFINE (scm_array_set_x, "array-set!", 2, 0, 1, 
-           (SCM v, SCM obj, SCM args),
-           "Set the element at the @code{(index1, index2)} element in @var{array} to\n"
-           "@var{new-value}.  The value returned by array-set! is unspecified.")
-#define FUNC_NAME s_scm_array_set_x           
+void
+scm_c_array_set_1_x (SCM array, SCM obj, ssize_t idx0)
+{
+  scm_t_array_handle handle;
+
+  scm_array_get_handle (array, &handle);
+  scm_array_handle_set (&handle, scm_array_handle_pos_1 (&handle, idx0),
+                        obj);
+  scm_array_handle_release (&handle);
+}
+
+
+void
+scm_c_array_set_2_x (SCM array, SCM obj, ssize_t idx0, ssize_t idx1)
+{
+  scm_t_array_handle handle;
+
+  scm_array_get_handle (array, &handle);
+  scm_array_handle_set (&handle, scm_array_handle_pos_2 (&handle, idx0, idx1),
+                        obj);
+  scm_array_handle_release (&handle);
+}
+
+
+SCM
+scm_array_set_x (SCM v, SCM obj, SCM args)
 {
   scm_t_array_handle handle;
 
@@ -225,8 +304,47 @@ SCM_DEFINE (scm_array_set_x, "array-set!", 2, 0, 1,
   scm_array_handle_release (&handle);
   return SCM_UNSPECIFIED;
 }
+
+
+SCM_DEFINE (scm_i_array_ref, "array-ref", 1, 2, 1,
+            (SCM v, SCM idx0, SCM idx1, SCM idxN),
+           "Return the element at the @code{(idx0, idx1, idxN...)}\n"
+            "position in array @var{v}.")
+#define FUNC_NAME s_scm_i_array_ref
+{
+  if (SCM_UNBNDP (idx0))
+    return scm_array_ref (v, SCM_EOL);
+  else if (SCM_UNBNDP (idx1))
+    return scm_c_array_ref_1 (v, scm_to_ssize_t (idx0));
+  else if (scm_is_null (idxN))
+    return scm_c_array_ref_2 (v, scm_to_ssize_t (idx0), scm_to_ssize_t (idx1));
+  else
+    return scm_array_ref (v, scm_cons (idx0, scm_cons (idx1, idxN)));
+}
 #undef FUNC_NAME
 
+
+SCM_DEFINE (scm_i_array_set_x, "array-set!", 2, 2, 1,
+            (SCM v, SCM obj, SCM idx0, SCM idx1, SCM idxN),
+           "Set the element at the @code{(idx0, idx1, idxN...)} position\n"
+           "in the array @var{v} to @var{obj}.  The value returned by\n"
+            "@code{array-set!} is unspecified.")
+#define FUNC_NAME s_scm_i_array_set_x
+{
+  if (SCM_UNBNDP (idx0))
+    scm_array_set_x (v, obj, SCM_EOL);
+  else if (SCM_UNBNDP (idx1))
+    scm_c_array_set_1_x (v, obj, scm_to_ssize_t (idx0));
+  else if (scm_is_null (idxN))
+    scm_c_array_set_2_x (v, obj, scm_to_ssize_t (idx0), scm_to_ssize_t (idx1));
+  else
+    scm_array_set_x (v, obj, scm_cons (idx0, scm_cons (idx1, idxN)));
+
+  return SCM_UNSPECIFIED;
+}
+#undef FUNC_NAME
+
+
 static SCM 
 array_to_list (scm_t_array_handle *h, size_t dim, unsigned long pos)
 {
@@ -250,8 +368,14 @@ array_to_list (scm_t_array_handle *h, size_t dim, unsigned long pos)
 
 SCM_DEFINE (scm_array_to_list, "array->list", 1, 0, 0, 
             (SCM array),
-           "FIXME description a list consisting of all the elements, in order, of\n"
-           "@var{array}.")
+           "Return a list representation of @var{array}.\n\n"
+            "It is easiest to specify the behavior of this function by\n"
+            "example:\n"
+            "@example\n"
+            "(array->list #0(a)) @result{} 1\n"
+            "(array->list #1(a b)) @result{} (a b)\n"
+            "(array->list #2((aa ab) (ba bb)) @result{} ((aa ab) (ba bb))\n"
+            "@end example\n")
 #define FUNC_NAME s_scm_array_to_list
 {
   scm_t_array_handle h;