From 2a5d0582d234b0a729e064e5c6cac56e90b8ddda Mon Sep 17 00:00:00 2001
From: Stuart Halloway <stuart@leo.(none)>
Date: Sun, 11 Dec 2011 07:52:01 -0500
Subject: [PATCH] CLJ-895 toArray(T[]), take 2

---
 src/jvm/clojure/lang/APersistentSet.java    |   14 +---------
 src/jvm/clojure/lang/APersistentVector.java |   14 +---------
 src/jvm/clojure/lang/ASeq.java              |   14 +---------
 src/jvm/clojure/lang/LazySeq.java           |   14 +---------
 src/jvm/clojure/lang/PersistentQueue.java   |   38 +++++++++-----------------
 src/jvm/clojure/lang/RT.java                |   15 ++++++++++
 6 files changed, 32 insertions(+), 77 deletions(-)

diff --git a/src/jvm/clojure/lang/APersistentSet.java b/src/jvm/clojure/lang/APersistentSet.java
index 5e3864f..8d5ab0e 100644
--- a/src/jvm/clojure/lang/APersistentSet.java
+++ b/src/jvm/clojure/lang/APersistentSet.java
@@ -140,19 +140,7 @@ public boolean containsAll(Collection c){
 }
 
 public Object[] toArray(Object[] a){
-	if(a.length >= count())
-		{
-		ISeq s = seq();
-		for(int i = 0; s != null; ++i, s = s.next())
-			{
-			a[i] = s.first();
-			}
-		if(a.length > count())
-			a[count()] = null;
-		return a;
-		}
-	else
-		return toArray();
+    return RT.seqToPassedArray(seq(), a);
 }
 
 public int size(){
diff --git a/src/jvm/clojure/lang/APersistentVector.java b/src/jvm/clojure/lang/APersistentVector.java
index ef73c5b..2b37379 100644
--- a/src/jvm/clojure/lang/APersistentVector.java
+++ b/src/jvm/clojure/lang/APersistentVector.java
@@ -366,19 +366,7 @@ public boolean containsAll(Collection c){
 }
 
 public Object[] toArray(Object[] a){
-	if(a.length >= count())
-		{
-		ISeq s = seq();
-		for(int i = 0; s != null; ++i, s = s.next())
-			{
-			a[i] = s.first();
-			}
-		if(a.length > count())
-			a[count()] = null;
-		return a;
-		}
-	else
-		return toArray();
+    return RT.seqToPassedArray(seq(), a);
 }
 
 public int size(){
diff --git a/src/jvm/clojure/lang/ASeq.java b/src/jvm/clojure/lang/ASeq.java
index e5ae82d..5597f5f 100644
--- a/src/jvm/clojure/lang/ASeq.java
+++ b/src/jvm/clojure/lang/ASeq.java
@@ -175,19 +175,7 @@ public boolean containsAll(Collection c){
 }
 
 public Object[] toArray(Object[] a){
-	if(a.length >= count())
-		{
-		ISeq s = seq();
-		for(int i = 0; s != null; ++i, s = s.next())
-			{
-			a[i] = s.first();
-			}
-		if(a.length > count())
-			a[count()] = null;
-		return a;
-		}
-	else
-		return toArray();
+    return RT.seqToPassedArray(seq(), a);
 }
 
 public int size(){
diff --git a/src/jvm/clojure/lang/LazySeq.java b/src/jvm/clojure/lang/LazySeq.java
index 7fc613a..6e9e37c 100644
--- a/src/jvm/clojure/lang/LazySeq.java
+++ b/src/jvm/clojure/lang/LazySeq.java
@@ -174,19 +174,7 @@ public boolean containsAll(Collection c){
 }
 
 public Object[] toArray(Object[] a){
-	if(a.length >= count())
-		{
-		ISeq s = seq();
-		for(int i = 0; s != null; ++i, s = s.next())
-			{
-			a[i] = s.first();
-			}
-		if(a.length > count())
-			a[count()] = null;
-		return a;
-		}
-	else
-		return toArray();
+    return RT.seqToPassedArray(seq(), a);
 }
 
 public int size(){
diff --git a/src/jvm/clojure/lang/PersistentQueue.java b/src/jvm/clojure/lang/PersistentQueue.java
index 674fd79..a2171b4 100644
--- a/src/jvm/clojure/lang/PersistentQueue.java
+++ b/src/jvm/clojure/lang/PersistentQueue.java
@@ -17,24 +17,24 @@ import java.util.Iterator;
 /**
  * conses onto rear, peeks/pops from front
  * See Okasaki's Batched Queues
- * This differs in that it uses a PersistentVector as the rear, which is in-order,
+ * This differs in that it uses a PersistentVector as the rear, which is in-order,
  * so no reversing or suspensions required for persistent use
  */
 
-public class PersistentQueue extends Obj implements IPersistentList, Collection, Counted{
+public class PersistentQueue extends Obj implements IPersistentList, Collection, Counted{
 
-final public static PersistentQueue EMPTY = new PersistentQueue(null, 0, null, null);
+final public static PersistentQueue EMPTY = new PersistentQueue(null, 0, null, null);
 
 //*
-final int cnt;
+final int cnt;
 final ISeq f;
 final PersistentVector r;
 //static final int INITIAL_REAR_SIZE = 4;
 int _hash = -1;
 
-PersistentQueue(IPersistentMap meta, int cnt, ISeq f, PersistentVector r){
+PersistentQueue(IPersistentMap meta, int cnt, ISeq f, PersistentVector r){
 	super(meta);
-	this.cnt = cnt;
+	this.cnt = cnt;
 	this.f = f;
 	this.r = r;
 }
@@ -95,11 +95,11 @@ public PersistentQueue pop(){
 		f1 = RT.seq(r);
 		r1 = null;
 		}
-	return new PersistentQueue(meta(), cnt - 1, f1, r1);
+	return new PersistentQueue(meta(), cnt - 1, f1, r1);
 }
 
 public int count(){
-	return cnt;
+	return cnt;
 }
 
 public ISeq seq(){
@@ -110,17 +110,17 @@ public ISeq seq(){
 
 public PersistentQueue cons(Object o){
 	if(f == null)     //empty
-		return new PersistentQueue(meta(), cnt + 1, RT.list(o), null);
+		return new PersistentQueue(meta(), cnt + 1, RT.list(o), null);
 	else
-		return new PersistentQueue(meta(), cnt + 1, f, (r != null ? r : PersistentVector.EMPTY).cons(o));
+		return new PersistentQueue(meta(), cnt + 1, f, (r != null ? r : PersistentVector.EMPTY).cons(o));
 }
 
 public IPersistentCollection empty(){
-	return EMPTY.withMeta(meta());
+	return EMPTY.withMeta(meta());
 }
 
 public PersistentQueue withMeta(IPersistentMap meta){
-	return new PersistentQueue(meta, cnt, f, r);
+	return new PersistentQueue(meta, cnt, f, r);
 }
 
 static class Seq extends ASeq{
@@ -204,19 +204,7 @@ public boolean containsAll(Collection c){
 }
 
 public Object[] toArray(Object[] a){
-	if(a.length >= count())
-		{
-		ISeq s = seq();
-		for(int i = 0; s != null; ++i, s = s.next())
-			{
-			a[i] = s.first();
-			}
-		if(a.length >= count())
-			a[count()] = null;
-		return a;
-		}
-	else
-		return toArray();
+    return RT.seqToPassedArray(seq(), a);
 }
 
 public int size(){
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index e33c24c..3f746be 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -1568,6 +1568,21 @@ static public Object[] seqToArray(ISeq seq){
 	return ret;
 }
 
+    // supports java Collection.toArray(T[])
+    static public Object[] seqToPassedArray(ISeq seq, Object[] passed){
+        Object[] dest = passed;
+        int len = count(seq);
+        if (len > dest.length) {
+            dest = (Object[]) Array.newInstance(passed.getClass().getComponentType(), len);
+        }
+        for(int i = 0; seq != null; ++i, seq = seq.next())
+            dest[i] = seq.first();
+        if (len < passed.length) {
+            dest[len] = null;
+        }
+        return dest;
+    }
+
 static public Object seqToTypedArray(ISeq seq) {
 	Class type = (seq != null) ? seq.first().getClass() : Object.class;
 	return seqToTypedArray(type, seq);
-- 
1.7.4.1

