summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Halloway <stu@thinkrelevance.com>2010-04-21 11:57:31 -0400
committerStuart Halloway <stu@thinkrelevance.com>2010-04-21 12:47:36 -0400
commit15a2b2e553b078b7e482da822dcb9f8c28c2016c (patch)
tree5449acb2ef14524a57b4bdd5488f4f3cebc91812
parent662410d5bdf073e8d8f91dcf4a35de425672d542 (diff)
IPersistentCollection methods for VecSeq (see #297)
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
-rw-r--r--src/clj/clojure/gvec.clj24
-rw-r--r--test/clojure/test_clojure.clj1
-rw-r--r--test/clojure/test_clojure/vectors.clj61
3 files changed, 86 insertions, 0 deletions
diff --git a/src/clj/clojure/gvec.clj b/src/clj/clojure/gvec.clj
index 3f4c5f6e..6c025835 100644
--- a/src/clj/clojure/gvec.clj
+++ b/src/clj/clojure/gvec.clj
@@ -78,6 +78,30 @@
(more [this]
(let [s (.next this)]
(or s (clojure.lang.PersistentList/EMPTY))))
+ (cons [this o]
+ (clojure.lang.Cons. o this))
+ (count [this]
+ (loop [i 1
+ s (next this)]
+ (if s
+ (if (instance? clojure.lang.Counted s)
+ (+ i (.count s))
+ (recur (inc i) (next s)))
+ i)))
+ (equiv [this o]
+ (cond
+ (identical? this o) true
+ (or (instance? clojure.lang.Sequential o) (instance? java.util.List o))
+ (loop [me this
+ you (seq o)]
+ (if (nil? me)
+ (nil? you)
+ (and (clojure.lang.Util/equiv (first me) (first you))
+ (recur (next me) (next you)))))
+ :else false))
+ (empty [_]
+ clojure.lang.PersistentList/EMPTY)
+
clojure.lang.Seqable
(seq [this] this)
diff --git a/test/clojure/test_clojure.clj b/test/clojure/test_clojure.clj
index d29f7bb0..1cc4ab94 100644
--- a/test/clojure/test_clojure.clj
+++ b/test/clojure/test_clojure.clj
@@ -51,6 +51,7 @@
:protocols
:genclass
:main
+ :vectors
])
(def test-namespaces
diff --git a/test/clojure/test_clojure/vectors.clj b/test/clojure/test_clojure/vectors.clj
new file mode 100644
index 00000000..654a5b84
--- /dev/null
+++ b/test/clojure/test_clojure/vectors.clj
@@ -0,0 +1,61 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+
+; Author: Stuart Halloway
+
+(ns clojure.test-clojure.vectors
+ (:use clojure.test))
+
+(deftest test-vecseq
+ (let [r (range 100)
+ vs (into (vector-of :int) r)
+ vs-1 (next vs)
+ vs-32 (.chunkedNext (seq vs))]
+ (testing "="
+ (are [a b] (= a b)
+ vs vs
+ vs-1 vs-1
+ vs-32 vs-32)
+ (are [a b] (not= a b)
+ vs vs-1
+ vs-1 vs
+ vs vs-32
+ vs-32 vs))
+ (testing "IPersistentCollection.empty"
+ (are [a] (identical? clojure.lang.PersistentList/EMPTY (.empty (seq a)))
+ vs vs-1 vs-32))
+ (testing "IPersistentCollection.cons"
+ (are [result input] (= result (.cons input :foo))
+ [:foo 1] (seq (into (vector-of :int) [1]))))
+ (testing "IPersistentCollection.count"
+ (are [ct s] (= ct (.count (seq s)))
+ 100 vs
+ 99 vs-1
+ 68 vs-32)
+ ;; can't manufacture this scenario: ASeq defers to Counted, but
+ ;; LazySeq doesn't, so Counted never gets checked on reified seq below
+ #_(testing "hops to counted when available"
+ (is (= 200
+ (.count (concat
+ (seq vs)
+ (reify clojure.lang.ISeq
+ (seq [this] this)
+ clojure.lang.Counted
+ (count [_] 100))))))))
+ (testing "IPersistentCollection.equiv"
+ (are [a b] (true? (.equiv a b))
+ vs vs
+ vs-1 vs-1
+ vs-32 vs-32
+ vs r)
+ (are [a b] (false? (.equiv a b))
+ vs vs-1
+ vs-1 vs
+ vs vs-32
+ vs-32 vs
+ vs nil))))