summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2009-01-20 23:48:34 +0000
committerRich Hickey <richhickey@gmail.com>2009-01-20 23:48:34 +0000
commit06d3b59c23ef90c9410470652ed6fc408d360716 (patch)
treeebf9e5cf6ba2b73018cbb945e846872a8b60959a
parent9c1ca8132937642298ad3c4b4cee6fa464a36633 (diff)
added overloads for Atom.swap
fix RT.nth for Lists to use count only for RandomAccess
-rw-r--r--src/clj/clojure/core.clj5
-rw-r--r--src/jvm/clojure/lang/Atom.java49
-rw-r--r--src/jvm/clojure/lang/RT.java2
3 files changed, 52 insertions, 4 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index d21c3f02..1b0d1484 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -1197,7 +1197,10 @@
(apply f current-value-of-atom args). Note that f may be called
multiple times, and thus should be free of side effects. Returns
the value that was swapped in."
- [#^clojure.lang.Atom atom f & args] (.swap atom f args))
+ ([#^clojure.lang.Atom atom f] (.swap atom f))
+ ([#^clojure.lang.Atom atom f x] (.swap atom f x))
+ ([#^clojure.lang.Atom atom f x y] (.swap atom f x y))
+ ([#^clojure.lang.Atom atom f x y & args] (.swap atom f x y args)))
(defn compare-and-set!
"Atomically sets the value of atom to newval if and only if the
diff --git a/src/jvm/clojure/lang/Atom.java b/src/jvm/clojure/lang/Atom.java
index eb904c8f..3d02f6e4 100644
--- a/src/jvm/clojure/lang/Atom.java
+++ b/src/jvm/clojure/lang/Atom.java
@@ -30,11 +30,56 @@ public class Atom extends ARef{
return state.get();
}
- public Object swap(IFn f, ISeq args) throws Exception {
+ public Object swap(IFn f) throws Exception {
for(;;)
{
Object v = get();
- Object newv = f.applyTo(new Cons(v, args));
+ Object newv = f.invoke(v);
+ validate(newv);
+ if(state.compareAndSet(v,newv))
+ {
+ if(v != newv)
+ notifyWatches();
+ return newv;
+ }
+ }
+ }
+
+ public Object swap(IFn f, Object arg) throws Exception {
+ for(;;)
+ {
+ Object v = get();
+ Object newv = f.invoke(v,arg);
+ validate(newv);
+ if(state.compareAndSet(v,newv))
+ {
+ if(v != newv)
+ notifyWatches();
+ return newv;
+ }
+ }
+ }
+
+ public Object swap(IFn f, Object arg1, Object arg2) throws Exception {
+ for(;;)
+ {
+ Object v = get();
+ Object newv = f.invoke(v, arg1, arg2);
+ validate(newv);
+ if(state.compareAndSet(v,newv))
+ {
+ if(v != newv)
+ notifyWatches();
+ return newv;
+ }
+ }
+ }
+
+ public Object swap(IFn f, Object x, Object y, ISeq args) throws Exception {
+ for(;;)
+ {
+ Object v = get();
+ Object newv = f.applyTo(RT.listStar(v, x, y, args));
validate(newv);
if(state.compareAndSet(v,newv))
{
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index f5d97e83..a277f89e 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -760,7 +760,7 @@ static public Object nth(Object coll, int n, Object notFound){
return Reflector.prepRet(Array.get(coll, n));
return notFound;
}
- else if(coll instanceof List)
+ else if(coll instanceof RandomAccess)
{
List list = (List) coll;
if(n < list.size())