annotate src/clojure/lang/APersistentVector.java @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
rev   line source
rlm@10 1 /**
rlm@10 2 * Copyright (c) Rich Hickey. All rights reserved.
rlm@10 3 * The use and distribution terms for this software are covered by the
rlm@10 4 * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
rlm@10 5 * which can be found in the file epl-v10.html at the root of this distribution.
rlm@10 6 * By using this software in any fashion, you are agreeing to be bound by
rlm@10 7 * the terms of this license.
rlm@10 8 * You must not remove this notice, or any other, from this software.
rlm@10 9 **/
rlm@10 10
rlm@10 11 /* rich Dec 18, 2007 */
rlm@10 12
rlm@10 13 package clojure.lang;
rlm@10 14
rlm@10 15 import java.io.Serializable;
rlm@10 16 import java.util.*;
rlm@10 17
rlm@10 18 public abstract class APersistentVector extends AFn implements IPersistentVector, Iterable,
rlm@10 19 List,
rlm@10 20 RandomAccess, Comparable,
rlm@10 21 Serializable {
rlm@10 22 int _hash = -1;
rlm@10 23
rlm@10 24 public String toString(){
rlm@10 25 return RT.printString(this);
rlm@10 26 }
rlm@10 27
rlm@10 28 public ISeq seq(){
rlm@10 29 if(count() > 0)
rlm@10 30 return new Seq(this, 0);
rlm@10 31 return null;
rlm@10 32 }
rlm@10 33
rlm@10 34 public ISeq rseq(){
rlm@10 35 if(count() > 0)
rlm@10 36 return new RSeq(this, count() - 1);
rlm@10 37 return null;
rlm@10 38 }
rlm@10 39
rlm@10 40 static boolean doEquals(IPersistentVector v, Object obj){
rlm@10 41 if(v == obj) return true;
rlm@10 42 if(obj instanceof List || obj instanceof IPersistentVector)
rlm@10 43 {
rlm@10 44 Collection ma = (Collection) obj;
rlm@10 45 if(ma.size() != v.count() || ma.hashCode() != v.hashCode())
rlm@10 46 return false;
rlm@10 47 for(Iterator i1 = ((List) v).iterator(), i2 = ma.iterator();
rlm@10 48 i1.hasNext();)
rlm@10 49 {
rlm@10 50 if(!Util.equals(i1.next(), i2.next()))
rlm@10 51 return false;
rlm@10 52 }
rlm@10 53 return true;
rlm@10 54 }
rlm@10 55 // if(obj instanceof IPersistentVector)
rlm@10 56 // {
rlm@10 57 // IPersistentVector ma = (IPersistentVector) obj;
rlm@10 58 // if(ma.count() != v.count() || ma.hashCode() != v.hashCode())
rlm@10 59 // return false;
rlm@10 60 // for(int i = 0; i < v.count(); i++)
rlm@10 61 // {
rlm@10 62 // if(!Util.equal(v.nth(i), ma.nth(i)))
rlm@10 63 // return false;
rlm@10 64 // }
rlm@10 65 // }
rlm@10 66 else
rlm@10 67 {
rlm@10 68 if(!(obj instanceof Sequential))
rlm@10 69 return false;
rlm@10 70 ISeq ms = RT.seq(obj);
rlm@10 71 for(int i = 0; i < v.count(); i++, ms = ms.next())
rlm@10 72 {
rlm@10 73 if(ms == null || !Util.equals(v.nth(i), ms.first()))
rlm@10 74 return false;
rlm@10 75 }
rlm@10 76 if(ms != null)
rlm@10 77 return false;
rlm@10 78 }
rlm@10 79
rlm@10 80 return true;
rlm@10 81
rlm@10 82 }
rlm@10 83
rlm@10 84 static boolean doEquiv(IPersistentVector v, Object obj){
rlm@10 85 if(obj instanceof List || obj instanceof IPersistentVector)
rlm@10 86 {
rlm@10 87 Collection ma = (Collection) obj;
rlm@10 88 if(ma.size() != v.count())
rlm@10 89 return false;
rlm@10 90 for(Iterator i1 = ((List) v).iterator(), i2 = ma.iterator();
rlm@10 91 i1.hasNext();)
rlm@10 92 {
rlm@10 93 if(!Util.equiv(i1.next(), i2.next()))
rlm@10 94 return false;
rlm@10 95 }
rlm@10 96 return true;
rlm@10 97 }
rlm@10 98 // if(obj instanceof IPersistentVector)
rlm@10 99 // {
rlm@10 100 // IPersistentVector ma = (IPersistentVector) obj;
rlm@10 101 // if(ma.count() != v.count() || ma.hashCode() != v.hashCode())
rlm@10 102 // return false;
rlm@10 103 // for(int i = 0; i < v.count(); i++)
rlm@10 104 // {
rlm@10 105 // if(!Util.equal(v.nth(i), ma.nth(i)))
rlm@10 106 // return false;
rlm@10 107 // }
rlm@10 108 // }
rlm@10 109 else
rlm@10 110 {
rlm@10 111 if(!(obj instanceof Sequential))
rlm@10 112 return false;
rlm@10 113 ISeq ms = RT.seq(obj);
rlm@10 114 for(int i = 0; i < v.count(); i++, ms = ms.next())
rlm@10 115 {
rlm@10 116 if(ms == null || !Util.equiv(v.nth(i), ms.first()))
rlm@10 117 return false;
rlm@10 118 }
rlm@10 119 if(ms != null)
rlm@10 120 return false;
rlm@10 121 }
rlm@10 122
rlm@10 123 return true;
rlm@10 124
rlm@10 125 }
rlm@10 126
rlm@10 127 public boolean equals(Object obj){
rlm@10 128 return doEquals(this, obj);
rlm@10 129 }
rlm@10 130
rlm@10 131 public boolean equiv(Object obj){
rlm@10 132 return doEquiv(this, obj);
rlm@10 133 }
rlm@10 134
rlm@10 135 public int hashCode(){
rlm@10 136 if(_hash == -1)
rlm@10 137 {
rlm@10 138 int hash = 1;
rlm@10 139 Iterator i = iterator();
rlm@10 140 while(i.hasNext())
rlm@10 141 {
rlm@10 142 Object obj = i.next();
rlm@10 143 hash = 31 * hash + (obj == null ? 0 : obj.hashCode());
rlm@10 144 }
rlm@10 145 // int hash = 0;
rlm@10 146 // for(int i = 0; i < count(); i++)
rlm@10 147 // {
rlm@10 148 // hash = Util.hashCombine(hash, Util.hash(nth(i)));
rlm@10 149 // }
rlm@10 150 this._hash = hash;
rlm@10 151 }
rlm@10 152 return _hash;
rlm@10 153 }
rlm@10 154
rlm@10 155 public Object get(int index){
rlm@10 156 return nth(index);
rlm@10 157 }
rlm@10 158
rlm@10 159 public Object nth(int i, Object notFound){
rlm@10 160 if(i >= 0 && i < count())
rlm@10 161 return nth(i);
rlm@10 162 return notFound;
rlm@10 163 }
rlm@10 164
rlm@10 165 public Object remove(int i){
rlm@10 166 throw new UnsupportedOperationException();
rlm@10 167 }
rlm@10 168
rlm@10 169 public int indexOf(Object o){
rlm@10 170 for(int i = 0; i < count(); i++)
rlm@10 171 if(Util.equiv(nth(i), o))
rlm@10 172 return i;
rlm@10 173 return -1;
rlm@10 174 }
rlm@10 175
rlm@10 176 public int lastIndexOf(Object o){
rlm@10 177 for(int i = count() - 1; i >= 0; i--)
rlm@10 178 if(Util.equiv(nth(i), o))
rlm@10 179 return i;
rlm@10 180 return -1;
rlm@10 181 }
rlm@10 182
rlm@10 183 public ListIterator listIterator(){
rlm@10 184 return listIterator(0);
rlm@10 185 }
rlm@10 186
rlm@10 187 public ListIterator listIterator(final int index){
rlm@10 188 return new ListIterator(){
rlm@10 189 int nexti = index;
rlm@10 190
rlm@10 191 public boolean hasNext(){
rlm@10 192 return nexti < count();
rlm@10 193 }
rlm@10 194
rlm@10 195 public Object next(){
rlm@10 196 return nth(nexti++);
rlm@10 197 }
rlm@10 198
rlm@10 199 public boolean hasPrevious(){
rlm@10 200 return nexti > 0;
rlm@10 201 }
rlm@10 202
rlm@10 203 public Object previous(){
rlm@10 204 return nth(--nexti);
rlm@10 205 }
rlm@10 206
rlm@10 207 public int nextIndex(){
rlm@10 208 return nexti;
rlm@10 209 }
rlm@10 210
rlm@10 211 public int previousIndex(){
rlm@10 212 return nexti - 1;
rlm@10 213 }
rlm@10 214
rlm@10 215 public void remove(){
rlm@10 216 throw new UnsupportedOperationException();
rlm@10 217 }
rlm@10 218
rlm@10 219 public void set(Object o){
rlm@10 220 throw new UnsupportedOperationException();
rlm@10 221 }
rlm@10 222
rlm@10 223 public void add(Object o){
rlm@10 224 throw new UnsupportedOperationException();
rlm@10 225 }
rlm@10 226 };
rlm@10 227 }
rlm@10 228
rlm@10 229 public List subList(int fromIndex, int toIndex){
rlm@10 230 return (List) RT.subvec(this, fromIndex, toIndex);
rlm@10 231 }
rlm@10 232
rlm@10 233
rlm@10 234 public Object set(int i, Object o){
rlm@10 235 throw new UnsupportedOperationException();
rlm@10 236 }
rlm@10 237
rlm@10 238 public void add(int i, Object o){
rlm@10 239 throw new UnsupportedOperationException();
rlm@10 240 }
rlm@10 241
rlm@10 242 public boolean addAll(int i, Collection c){
rlm@10 243 throw new UnsupportedOperationException();
rlm@10 244 }
rlm@10 245
rlm@10 246
rlm@10 247 public Object invoke(Object arg1) throws Exception{
rlm@10 248 if(Util.isInteger(arg1))
rlm@10 249 return nth(((Number) arg1).intValue());
rlm@10 250 throw new IllegalArgumentException("Key must be integer");
rlm@10 251 }
rlm@10 252
rlm@10 253 public Iterator iterator(){
rlm@10 254 //todo - something more efficient
rlm@10 255 return new Iterator(){
rlm@10 256 int i = 0;
rlm@10 257
rlm@10 258 public boolean hasNext(){
rlm@10 259 return i < count();
rlm@10 260 }
rlm@10 261
rlm@10 262 public Object next(){
rlm@10 263 return nth(i++);
rlm@10 264 }
rlm@10 265
rlm@10 266 public void remove(){
rlm@10 267 throw new UnsupportedOperationException();
rlm@10 268 }
rlm@10 269 };
rlm@10 270 }
rlm@10 271
rlm@10 272 public Object peek(){
rlm@10 273 if(count() > 0)
rlm@10 274 return nth(count() - 1);
rlm@10 275 return null;
rlm@10 276 }
rlm@10 277
rlm@10 278 public boolean containsKey(Object key){
rlm@10 279 if(!(Util.isInteger(key)))
rlm@10 280 return false;
rlm@10 281 int i = ((Number) key).intValue();
rlm@10 282 return i >= 0 && i < count();
rlm@10 283 }
rlm@10 284
rlm@10 285 public IMapEntry entryAt(Object key){
rlm@10 286 if(Util.isInteger(key))
rlm@10 287 {
rlm@10 288 int i = ((Number) key).intValue();
rlm@10 289 if(i >= 0 && i < count())
rlm@10 290 return new MapEntry(key, nth(i));
rlm@10 291 }
rlm@10 292 return null;
rlm@10 293 }
rlm@10 294
rlm@10 295 public IPersistentVector assoc(Object key, Object val){
rlm@10 296 if(Util.isInteger(key))
rlm@10 297 {
rlm@10 298 int i = ((Number) key).intValue();
rlm@10 299 return assocN(i, val);
rlm@10 300 }
rlm@10 301 throw new IllegalArgumentException("Key must be integer");
rlm@10 302 }
rlm@10 303
rlm@10 304 public Object valAt(Object key, Object notFound){
rlm@10 305 if(Util.isInteger(key))
rlm@10 306 {
rlm@10 307 int i = ((Number) key).intValue();
rlm@10 308 if(i >= 0 && i < count())
rlm@10 309 return nth(i);
rlm@10 310 }
rlm@10 311 return notFound;
rlm@10 312 }
rlm@10 313
rlm@10 314 public Object valAt(Object key){
rlm@10 315 return valAt(key, null);
rlm@10 316 }
rlm@10 317
rlm@10 318 // java.util.Collection implementation
rlm@10 319
rlm@10 320 public Object[] toArray(){
rlm@10 321 return RT.seqToArray(seq());
rlm@10 322 }
rlm@10 323
rlm@10 324 public boolean add(Object o){
rlm@10 325 throw new UnsupportedOperationException();
rlm@10 326 }
rlm@10 327
rlm@10 328 public boolean remove(Object o){
rlm@10 329 throw new UnsupportedOperationException();
rlm@10 330 }
rlm@10 331
rlm@10 332 public boolean addAll(Collection c){
rlm@10 333 throw new UnsupportedOperationException();
rlm@10 334 }
rlm@10 335
rlm@10 336 public void clear(){
rlm@10 337 throw new UnsupportedOperationException();
rlm@10 338 }
rlm@10 339
rlm@10 340 public boolean retainAll(Collection c){
rlm@10 341 throw new UnsupportedOperationException();
rlm@10 342 }
rlm@10 343
rlm@10 344 public boolean removeAll(Collection c){
rlm@10 345 throw new UnsupportedOperationException();
rlm@10 346 }
rlm@10 347
rlm@10 348 public boolean containsAll(Collection c){
rlm@10 349 for(Object o : c)
rlm@10 350 {
rlm@10 351 if(!contains(o))
rlm@10 352 return false;
rlm@10 353 }
rlm@10 354 return true;
rlm@10 355 }
rlm@10 356
rlm@10 357 public Object[] toArray(Object[] a){
rlm@10 358 if(a.length >= count())
rlm@10 359 {
rlm@10 360 ISeq s = seq();
rlm@10 361 for(int i = 0; s != null; ++i, s = s.next())
rlm@10 362 {
rlm@10 363 a[i] = s.first();
rlm@10 364 }
rlm@10 365 if(a.length > count())
rlm@10 366 a[count()] = null;
rlm@10 367 return a;
rlm@10 368 }
rlm@10 369 else
rlm@10 370 return toArray();
rlm@10 371 }
rlm@10 372
rlm@10 373 public int size(){
rlm@10 374 return count();
rlm@10 375 }
rlm@10 376
rlm@10 377 public boolean isEmpty(){
rlm@10 378 return count() == 0;
rlm@10 379 }
rlm@10 380
rlm@10 381 public boolean contains(Object o){
rlm@10 382 for(ISeq s = seq(); s != null; s = s.next())
rlm@10 383 {
rlm@10 384 if(Util.equiv(s.first(), o))
rlm@10 385 return true;
rlm@10 386 }
rlm@10 387 return false;
rlm@10 388 }
rlm@10 389
rlm@10 390 public int length(){
rlm@10 391 return count();
rlm@10 392 }
rlm@10 393
rlm@10 394 public int compareTo(Object o){
rlm@10 395 IPersistentVector v = (IPersistentVector) o;
rlm@10 396 if(count() < v.count())
rlm@10 397 return -1;
rlm@10 398 else if(count() > v.count())
rlm@10 399 return 1;
rlm@10 400 for(int i = 0; i < count(); i++)
rlm@10 401 {
rlm@10 402 int c = Util.compare(nth(i),v.nth(i));
rlm@10 403 if(c != 0)
rlm@10 404 return c;
rlm@10 405 }
rlm@10 406 return 0;
rlm@10 407 }
rlm@10 408
rlm@10 409 static class Seq extends ASeq implements IndexedSeq, IReduce{
rlm@10 410 //todo - something more efficient
rlm@10 411 final IPersistentVector v;
rlm@10 412 final int i;
rlm@10 413
rlm@10 414
rlm@10 415 public Seq(IPersistentVector v, int i){
rlm@10 416 this.v = v;
rlm@10 417 this.i = i;
rlm@10 418 }
rlm@10 419
rlm@10 420 Seq(IPersistentMap meta, IPersistentVector v, int i){
rlm@10 421 super(meta);
rlm@10 422 this.v = v;
rlm@10 423 this.i = i;
rlm@10 424 }
rlm@10 425
rlm@10 426 public Object first(){
rlm@10 427 return v.nth(i);
rlm@10 428 }
rlm@10 429
rlm@10 430 public ISeq next(){
rlm@10 431 if(i + 1 < v.count())
rlm@10 432 return new APersistentVector.Seq(v, i + 1);
rlm@10 433 return null;
rlm@10 434 }
rlm@10 435
rlm@10 436 public int index(){
rlm@10 437 return i;
rlm@10 438 }
rlm@10 439
rlm@10 440 public int count(){
rlm@10 441 return v.count() - i;
rlm@10 442 }
rlm@10 443
rlm@10 444 public APersistentVector.Seq withMeta(IPersistentMap meta){
rlm@10 445 return new APersistentVector.Seq(meta, v, i);
rlm@10 446 }
rlm@10 447
rlm@10 448 public Object reduce(IFn f) throws Exception{
rlm@10 449 Object ret = v.nth(i);
rlm@10 450 for(int x = i + 1; x < v.count(); x++)
rlm@10 451 ret = f.invoke(ret, v.nth(x));
rlm@10 452 return ret;
rlm@10 453 }
rlm@10 454
rlm@10 455 public Object reduce(IFn f, Object start) throws Exception{
rlm@10 456 Object ret = f.invoke(start, v.nth(i));
rlm@10 457 for(int x = i + 1; x < v.count(); x++)
rlm@10 458 ret = f.invoke(ret, v.nth(x));
rlm@10 459 return ret;
rlm@10 460 }
rlm@10 461 }
rlm@10 462
rlm@10 463 public static class RSeq extends ASeq implements IndexedSeq, Counted{
rlm@10 464 final IPersistentVector v;
rlm@10 465 final int i;
rlm@10 466
rlm@10 467 public RSeq(IPersistentVector vector, int i){
rlm@10 468 this.v = vector;
rlm@10 469 this.i = i;
rlm@10 470 }
rlm@10 471
rlm@10 472 RSeq(IPersistentMap meta, IPersistentVector v, int i){
rlm@10 473 super(meta);
rlm@10 474 this.v = v;
rlm@10 475 this.i = i;
rlm@10 476 }
rlm@10 477
rlm@10 478 public Object first(){
rlm@10 479 return v.nth(i);
rlm@10 480 }
rlm@10 481
rlm@10 482 public ISeq next(){
rlm@10 483 if(i > 0)
rlm@10 484 return new APersistentVector.RSeq(v, i - 1);
rlm@10 485 return null;
rlm@10 486 }
rlm@10 487
rlm@10 488 public int index(){
rlm@10 489 return i;
rlm@10 490 }
rlm@10 491
rlm@10 492 public int count(){
rlm@10 493 return i + 1;
rlm@10 494 }
rlm@10 495
rlm@10 496 public APersistentVector.RSeq withMeta(IPersistentMap meta){
rlm@10 497 return new APersistentVector.RSeq(meta, v, i);
rlm@10 498 }
rlm@10 499 }
rlm@10 500
rlm@10 501 static class SubVector extends APersistentVector implements IObj{
rlm@10 502 final IPersistentVector v;
rlm@10 503 final int start;
rlm@10 504 final int end;
rlm@10 505 final IPersistentMap _meta;
rlm@10 506
rlm@10 507
rlm@10 508
rlm@10 509 public SubVector(IPersistentMap meta, IPersistentVector v, int start, int end){
rlm@10 510 this._meta = meta;
rlm@10 511
rlm@10 512 if(v instanceof APersistentVector.SubVector)
rlm@10 513 {
rlm@10 514 APersistentVector.SubVector sv = (APersistentVector.SubVector) v;
rlm@10 515 start += sv.start;
rlm@10 516 end += sv.start;
rlm@10 517 v = sv.v;
rlm@10 518 }
rlm@10 519 this.v = v;
rlm@10 520 this.start = start;
rlm@10 521 this.end = end;
rlm@10 522 }
rlm@10 523
rlm@10 524 public Object nth(int i){
rlm@10 525 if(start + i >= end)
rlm@10 526 throw new IndexOutOfBoundsException();
rlm@10 527 return v.nth(start + i);
rlm@10 528 }
rlm@10 529
rlm@10 530 public IPersistentVector assocN(int i, Object val){
rlm@10 531 if(start + i > end)
rlm@10 532 throw new IndexOutOfBoundsException();
rlm@10 533 else if(start + i == end)
rlm@10 534 return cons(val);
rlm@10 535 return new SubVector(_meta, v.assocN(start + i, val), start, end);
rlm@10 536 }
rlm@10 537
rlm@10 538 public int count(){
rlm@10 539 return end - start;
rlm@10 540 }
rlm@10 541
rlm@10 542 public IPersistentVector cons(Object o){
rlm@10 543 return new SubVector(_meta, v.assocN(end, o), start, end + 1);
rlm@10 544 }
rlm@10 545
rlm@10 546 public IPersistentCollection empty(){
rlm@10 547 return PersistentVector.EMPTY.withMeta(meta());
rlm@10 548 }
rlm@10 549
rlm@10 550 public IPersistentStack pop(){
rlm@10 551 if(end - 1 == start)
rlm@10 552 {
rlm@10 553 return PersistentVector.EMPTY;
rlm@10 554 }
rlm@10 555 return new SubVector(_meta, v, start, end - 1);
rlm@10 556 }
rlm@10 557
rlm@10 558 public SubVector withMeta(IPersistentMap meta){
rlm@10 559 if(meta == _meta)
rlm@10 560 return this;
rlm@10 561 return new SubVector(meta, v, start, end);
rlm@10 562 }
rlm@10 563
rlm@10 564 public IPersistentMap meta(){
rlm@10 565 return _meta;
rlm@10 566 }
rlm@10 567 }
rlm@10 568 }