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 }
|