summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <Ninja@.(none)>2009-11-11 16:34:14 +1100
committerRich Hickey <richhickey@gmail.com>2009-11-24 08:30:52 -0500
commitf966d6efab1463be32213d87343aa17c9003234b (patch)
tree8a2ed5a7014212dc864c48bc596ae5fe66db539d
parentfc5157d5b85b62dbf8e809d3caf014c792abd718 (diff)
#209 Unifying array support for primatives
Signed-off-by: Rich Hickey <richhickey@gmail.com>
-rw-r--r--src/clj/clojure/core.clj46
-rw-r--r--src/jvm/clojure/lang/Numbers.java140
-rw-r--r--test/clojure/test_clojure/numbers.clj15
3 files changed, 200 insertions, 1 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 535acfcb..89929e02 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -3546,6 +3546,34 @@
([size-or-seq] (. clojure.lang.Numbers float_array size-or-seq))
([size init-val-or-seq] (. clojure.lang.Numbers float_array size init-val-or-seq)))
+(defn boolean-array
+ "Creates an array of booleans"
+ {:inline (fn [& args] `(. clojure.lang.Numbers boolean_array ~@args))
+ :inline-arities #{1 2}}
+ ([size-or-seq] (. clojure.lang.Numbers boolean_array size-or-seq))
+ ([size init-val-or-seq] (. clojure.lang.Numbers boolean_array size init-val-or-seq)))
+
+(defn byte-array
+ "Creates an array of bytes"
+ {:inline (fn [& args] `(. clojure.lang.Numbers byte_array ~@args))
+ :inline-arities #{1 2}}
+ ([size-or-seq] (. clojure.lang.Numbers byte_array size-or-seq))
+ ([size init-val-or-seq] (. clojure.lang.Numbers byte_array size init-val-or-seq)))
+
+(defn char-array
+ "Creates an array of chars"
+ {:inline (fn [& args] `(. clojure.lang.Numbers char_array ~@args))
+ :inline-arities #{1 2}}
+ ([size-or-seq] (. clojure.lang.Numbers char_array size-or-seq))
+ ([size init-val-or-seq] (. clojure.lang.Numbers char_array size init-val-or-seq)))
+
+(defn short-array
+ "Creates an array of shorts"
+ {:inline (fn [& args] `(. clojure.lang.Numbers short_array ~@args))
+ :inline-arities #{1 2}}
+ ([size-or-seq] (. clojure.lang.Numbers short_array size-or-seq))
+ ([size init-val-or-seq] (. clojure.lang.Numbers short_array size init-val-or-seq)))
+
(defn double-array
"Creates an array of doubles"
{:inline (fn [& args] `(. clojure.lang.Numbers double_array ~@args))
@@ -3561,12 +3589,28 @@
([size init-val-or-seq] (. clojure.lang.Numbers int_array size init-val-or-seq)))
(defn long-array
- "Creates an array of ints"
+ "Creates an array of longs"
{:inline (fn [& args] `(. clojure.lang.Numbers long_array ~@args))
:inline-arities #{1 2}}
([size-or-seq] (. clojure.lang.Numbers long_array size-or-seq))
([size init-val-or-seq] (. clojure.lang.Numbers long_array size init-val-or-seq)))
+(definline booleans
+ "Casts to boolean[]"
+ [xs] `(. clojure.lang.Numbers booleans ~xs))
+
+(definline bytes
+ "Casts to bytes[]"
+ [xs] `(. clojure.lang.Numbers bytes ~xs))
+
+(definline chars
+ "Casts to chars[]"
+ [xs] `(. clojure.lang.Numbers chars ~xs))
+
+(definline shorts
+ "Casts to shorts[]"
+ [xs] `(. clojure.lang.Numbers shorts ~xs))
+
(definline floats
"Casts to float[]"
[xs] `(. clojure.lang.Numbers floats ~xs))
diff --git a/src/jvm/clojure/lang/Numbers.java b/src/jvm/clojure/lang/Numbers.java
index 8d5fd855..04002085 100644
--- a/src/jvm/clojure/lang/Numbers.java
+++ b/src/jvm/clojure/lang/Numbers.java
@@ -1537,6 +1537,146 @@ static public long[] long_array(Object sizeOrSeq){
}
}
+static public short[] short_array(int size, Object init){
+ short[] ret = new short[size];
+ if(init instanceof Short)
+ {
+ short s = (Short) init;
+ for(int i = 0; i < ret.length; i++)
+ ret[i] = s;
+ }
+ else
+ {
+ ISeq s = RT.seq(init);
+ for(int i = 0; i < size && s != null; i++, s = s.next())
+ ret[i] = (Short) s.first();
+ }
+ return ret;
+}
+
+static public short[] short_array(Object sizeOrSeq){
+ if(sizeOrSeq instanceof Number)
+ return new short[((Number) sizeOrSeq).intValue()];
+ else
+ {
+ ISeq s = RT.seq(sizeOrSeq);
+ int size = RT.count(s);
+ short[] ret = new short[size];
+ for(int i = 0; i < size && s != null; i++, s = s.next())
+ ret[i] = (Short) s.first();
+ return ret;
+ }
+}
+
+static public char[] char_array(int size, Object init){
+ char[] ret = new char[size];
+ if(init instanceof Character)
+ {
+ char c = (Character) init;
+ for(int i = 0; i < ret.length; i++)
+ ret[i] = c;
+ }
+ else
+ {
+ ISeq s = RT.seq(init);
+ for(int i = 0; i < size && s != null; i++, s = s.next())
+ ret[i] = (Character) s.first();
+ }
+ return ret;
+}
+
+static public char[] char_array(Object sizeOrSeq){
+ if(sizeOrSeq instanceof Number)
+ return new char[((Number) sizeOrSeq).intValue()];
+ else
+ {
+ ISeq s = RT.seq(sizeOrSeq);
+ int size = RT.count(s);
+ char[] ret = new char[size];
+ for(int i = 0; i < size && s != null; i++, s = s.next())
+ ret[i] = (Character) s.first();
+ return ret;
+ }
+}
+
+static public byte[] byte_array(int size, Object init){
+ byte[] ret = new byte[size];
+ if(init instanceof Byte)
+ {
+ byte b = (Byte) init;
+ for(int i = 0; i < ret.length; i++)
+ ret[i] = b;
+ }
+ else
+ {
+ ISeq s = RT.seq(init);
+ for(int i = 0; i < size && s != null; i++, s = s.next())
+ ret[i] = (Byte) s.first();
+ }
+ return ret;
+}
+
+static public byte[] byte_array(Object sizeOrSeq){
+ if(sizeOrSeq instanceof Number)
+ return new byte[((Number) sizeOrSeq).intValue()];
+ else
+ {
+ ISeq s = RT.seq(sizeOrSeq);
+ int size = RT.count(s);
+ byte[] ret = new byte[size];
+ for(int i = 0; i < size && s != null; i++, s = s.next())
+ ret[i] = (Byte)s.first();
+ return ret;
+ }
+}
+
+static public boolean[] boolean_array(int size, Object init){
+ boolean[] ret = new boolean[size];
+ if(init instanceof Boolean)
+ {
+ boolean b = (Boolean) init;
+ for(int i = 0; i < ret.length; i++)
+ ret[i] = b;
+ }
+ else
+ {
+ ISeq s = RT.seq(init);
+ for(int i = 0; i < size && s != null; i++, s = s.next())
+ ret[i] = (Boolean)s.first();
+ }
+ return ret;
+}
+
+static public boolean[] boolean_array(Object sizeOrSeq){
+ if(sizeOrSeq instanceof Number)
+ return new boolean[((Number) sizeOrSeq).intValue()];
+ else
+ {
+ ISeq s = RT.seq(sizeOrSeq);
+ int size = RT.count(s);
+ boolean[] ret = new boolean[size];
+ for(int i = 0; i < size && s != null; i++, s = s.next())
+ ret[i] = (Boolean)s.first();
+ return ret;
+ }
+}
+
+static public boolean[] booleans(Object array){
+ return (boolean[]) array;
+}
+
+static public byte[] bytes(Object array){
+ return (byte[]) array;
+}
+
+static public char[] chars(Object array){
+ return (char[]) array;
+}
+
+static public short[] shorts(Object array){
+ return (short[]) array;
+}
+
static public float[] floats(Object array){
return (float[]) array;
}
diff --git a/test/clojure/test_clojure/numbers.clj b/test/clojure/test_clojure/numbers.clj
index 98157eb5..72bb7d03 100644
--- a/test/clojure/test_clojure/numbers.clj
+++ b/test/clojure/test_clojure/numbers.clj
@@ -418,3 +418,18 @@ Math/pow overflows to Infinity."
1 (bit-shift-right (expt 2 32) 32)
1 (bit-shift-right (expt 2 10000) 10000)
))
+
+
+;; arrays
+(deftest test-array-types
+ (are [x y z] (= (Class/forName x) (class y) (class z))
+ "[Z" (boolean-array 1) (booleans (boolean-array 1 true))
+ "[B" (byte-array 1) (bytes (byte-array 1 (byte 1)))
+ "[C" (char-array 1) (chars (char-array 1 \a))
+ "[S" (short-array 1) (shorts (short-array 1 (short 1)))
+ "[F" (float-array 1) (floats (float-array 1 1))
+ "[D" (double-array 1) (doubles (double-array 1 1))
+ "[I" (int-array 1) (ints (int-array 1 1))
+ "[J" (long-array 1) (longs (long-array 1 1))))
+
+