diff options
author | unknown <Ninja@.(none)> | 2009-11-11 16:34:14 +1100 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-11-24 08:30:52 -0500 |
commit | f966d6efab1463be32213d87343aa17c9003234b (patch) | |
tree | 8a2ed5a7014212dc864c48bc596ae5fe66db539d | |
parent | fc5157d5b85b62dbf8e809d3caf014c792abd718 (diff) |
#209 Unifying array support for primatives
Signed-off-by: Rich Hickey <richhickey@gmail.com>
-rw-r--r-- | src/clj/clojure/core.clj | 46 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Numbers.java | 140 | ||||
-rw-r--r-- | test/clojure/test_clojure/numbers.clj | 15 |
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)))) + + |