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 Jan 31, 2009 */
|
rlm@10
|
12
|
rlm@10
|
13 package clojure.lang;
|
rlm@10
|
14
|
rlm@10
|
15 import java.util.*;
|
rlm@10
|
16
|
rlm@10
|
17 public final class LazySeq extends Obj implements ISeq, List{
|
rlm@10
|
18
|
rlm@10
|
19 private IFn fn;
|
rlm@10
|
20 private Object sv;
|
rlm@10
|
21 private ISeq s;
|
rlm@10
|
22
|
rlm@10
|
23 public LazySeq(IFn fn){
|
rlm@10
|
24 this.fn = fn;
|
rlm@10
|
25 }
|
rlm@10
|
26
|
rlm@10
|
27 private LazySeq(IPersistentMap meta, ISeq s){
|
rlm@10
|
28 super(meta);
|
rlm@10
|
29 this.fn = null;
|
rlm@10
|
30 this.s = s;
|
rlm@10
|
31 }
|
rlm@10
|
32
|
rlm@10
|
33 public Obj withMeta(IPersistentMap meta){
|
rlm@10
|
34 return new LazySeq(meta, seq());
|
rlm@10
|
35 }
|
rlm@10
|
36
|
rlm@10
|
37 final synchronized Object sval(){
|
rlm@10
|
38 if(fn != null)
|
rlm@10
|
39 {
|
rlm@10
|
40 try
|
rlm@10
|
41 {
|
rlm@10
|
42 sv = fn.invoke();
|
rlm@10
|
43 fn = null;
|
rlm@10
|
44 }
|
rlm@10
|
45 catch(Exception e)
|
rlm@10
|
46 {
|
rlm@10
|
47 throw new RuntimeException(e);
|
rlm@10
|
48 }
|
rlm@10
|
49 }
|
rlm@10
|
50 if(sv != null)
|
rlm@10
|
51 return sv;
|
rlm@10
|
52 return s;
|
rlm@10
|
53 }
|
rlm@10
|
54
|
rlm@10
|
55 final synchronized public ISeq seq(){
|
rlm@10
|
56 sval();
|
rlm@10
|
57 if(sv != null)
|
rlm@10
|
58 {
|
rlm@10
|
59 Object ls = sv;
|
rlm@10
|
60 sv = null;
|
rlm@10
|
61 while(ls instanceof LazySeq)
|
rlm@10
|
62 {
|
rlm@10
|
63 ls = ((LazySeq)ls).sval();
|
rlm@10
|
64 }
|
rlm@10
|
65 s = RT.seq(ls);
|
rlm@10
|
66 }
|
rlm@10
|
67 return s;
|
rlm@10
|
68 }
|
rlm@10
|
69
|
rlm@10
|
70 public int count(){
|
rlm@10
|
71 int c = 0;
|
rlm@10
|
72 for(ISeq s = seq(); s != null; s = s.next())
|
rlm@10
|
73 ++c;
|
rlm@10
|
74 return c;
|
rlm@10
|
75 }
|
rlm@10
|
76
|
rlm@10
|
77 public Object first(){
|
rlm@10
|
78 seq();
|
rlm@10
|
79 if(s == null)
|
rlm@10
|
80 return null;
|
rlm@10
|
81 return s.first();
|
rlm@10
|
82 }
|
rlm@10
|
83
|
rlm@10
|
84 public ISeq next(){
|
rlm@10
|
85 seq();
|
rlm@10
|
86 if(s == null)
|
rlm@10
|
87 return null;
|
rlm@10
|
88 return s.next();
|
rlm@10
|
89 }
|
rlm@10
|
90
|
rlm@10
|
91 public ISeq more(){
|
rlm@10
|
92 seq();
|
rlm@10
|
93 if(s == null)
|
rlm@10
|
94 return PersistentList.EMPTY;
|
rlm@10
|
95 return s.more();
|
rlm@10
|
96 }
|
rlm@10
|
97
|
rlm@10
|
98 public ISeq cons(Object o){
|
rlm@10
|
99 return RT.cons(o, seq());
|
rlm@10
|
100 }
|
rlm@10
|
101
|
rlm@10
|
102 public IPersistentCollection empty(){
|
rlm@10
|
103 return PersistentList.EMPTY;
|
rlm@10
|
104 }
|
rlm@10
|
105
|
rlm@10
|
106 public boolean equiv(Object o){
|
rlm@10
|
107 return equals(o);
|
rlm@10
|
108 }
|
rlm@10
|
109
|
rlm@10
|
110 public int hashCode(){
|
rlm@10
|
111 return Util.hash(seq());
|
rlm@10
|
112 }
|
rlm@10
|
113
|
rlm@10
|
114 public boolean equals(Object o){
|
rlm@10
|
115 ISeq s = seq();
|
rlm@10
|
116 if(s != null)
|
rlm@10
|
117 return s.equiv(o);
|
rlm@10
|
118 else
|
rlm@10
|
119 return (o instanceof Sequential || o instanceof List) && RT.seq(o) == null;
|
rlm@10
|
120 }
|
rlm@10
|
121
|
rlm@10
|
122
|
rlm@10
|
123 // java.util.Collection implementation
|
rlm@10
|
124
|
rlm@10
|
125 public Object[] toArray(){
|
rlm@10
|
126 return RT.seqToArray(seq());
|
rlm@10
|
127 }
|
rlm@10
|
128
|
rlm@10
|
129 public boolean add(Object o){
|
rlm@10
|
130 throw new UnsupportedOperationException();
|
rlm@10
|
131 }
|
rlm@10
|
132
|
rlm@10
|
133 public boolean remove(Object o){
|
rlm@10
|
134 throw new UnsupportedOperationException();
|
rlm@10
|
135 }
|
rlm@10
|
136
|
rlm@10
|
137 public boolean addAll(Collection c){
|
rlm@10
|
138 throw new UnsupportedOperationException();
|
rlm@10
|
139 }
|
rlm@10
|
140
|
rlm@10
|
141 public void clear(){
|
rlm@10
|
142 throw new UnsupportedOperationException();
|
rlm@10
|
143 }
|
rlm@10
|
144
|
rlm@10
|
145 public boolean retainAll(Collection c){
|
rlm@10
|
146 throw new UnsupportedOperationException();
|
rlm@10
|
147 }
|
rlm@10
|
148
|
rlm@10
|
149 public boolean removeAll(Collection c){
|
rlm@10
|
150 throw new UnsupportedOperationException();
|
rlm@10
|
151 }
|
rlm@10
|
152
|
rlm@10
|
153 public boolean containsAll(Collection c){
|
rlm@10
|
154 for(Object o : c)
|
rlm@10
|
155 {
|
rlm@10
|
156 if(!contains(o))
|
rlm@10
|
157 return false;
|
rlm@10
|
158 }
|
rlm@10
|
159 return true;
|
rlm@10
|
160 }
|
rlm@10
|
161
|
rlm@10
|
162 public Object[] toArray(Object[] a){
|
rlm@10
|
163 if(a.length >= count())
|
rlm@10
|
164 {
|
rlm@10
|
165 ISeq s = seq();
|
rlm@10
|
166 for(int i = 0; s != null; ++i, s = s.next())
|
rlm@10
|
167 {
|
rlm@10
|
168 a[i] = s.first();
|
rlm@10
|
169 }
|
rlm@10
|
170 if(a.length > count())
|
rlm@10
|
171 a[count()] = null;
|
rlm@10
|
172 return a;
|
rlm@10
|
173 }
|
rlm@10
|
174 else
|
rlm@10
|
175 return toArray();
|
rlm@10
|
176 }
|
rlm@10
|
177
|
rlm@10
|
178 public int size(){
|
rlm@10
|
179 return count();
|
rlm@10
|
180 }
|
rlm@10
|
181
|
rlm@10
|
182 public boolean isEmpty(){
|
rlm@10
|
183 return seq() == null;
|
rlm@10
|
184 }
|
rlm@10
|
185
|
rlm@10
|
186 public boolean contains(Object o){
|
rlm@10
|
187 for(ISeq s = seq(); s != null; s = s.next())
|
rlm@10
|
188 {
|
rlm@10
|
189 if(Util.equiv(s.first(), o))
|
rlm@10
|
190 return true;
|
rlm@10
|
191 }
|
rlm@10
|
192 return false;
|
rlm@10
|
193 }
|
rlm@10
|
194
|
rlm@10
|
195 public Iterator iterator(){
|
rlm@10
|
196 return new SeqIterator(seq());
|
rlm@10
|
197 }
|
rlm@10
|
198
|
rlm@10
|
199 //////////// List stuff /////////////////
|
rlm@10
|
200 private List reify(){
|
rlm@10
|
201 return new ArrayList(this);
|
rlm@10
|
202 }
|
rlm@10
|
203
|
rlm@10
|
204 public List subList(int fromIndex, int toIndex){
|
rlm@10
|
205 return reify().subList(fromIndex, toIndex);
|
rlm@10
|
206 }
|
rlm@10
|
207
|
rlm@10
|
208 public Object set(int index, Object element){
|
rlm@10
|
209 throw new UnsupportedOperationException();
|
rlm@10
|
210 }
|
rlm@10
|
211
|
rlm@10
|
212 public Object remove(int index){
|
rlm@10
|
213 throw new UnsupportedOperationException();
|
rlm@10
|
214 }
|
rlm@10
|
215
|
rlm@10
|
216 public int indexOf(Object o){
|
rlm@10
|
217 ISeq s = seq();
|
rlm@10
|
218 for(int i = 0; s != null; s = s.next(), i++)
|
rlm@10
|
219 {
|
rlm@10
|
220 if(Util.equiv(s.first(), o))
|
rlm@10
|
221 return i;
|
rlm@10
|
222 }
|
rlm@10
|
223 return -1;
|
rlm@10
|
224 }
|
rlm@10
|
225
|
rlm@10
|
226 public int lastIndexOf(Object o){
|
rlm@10
|
227 return reify().lastIndexOf(o);
|
rlm@10
|
228 }
|
rlm@10
|
229
|
rlm@10
|
230 public ListIterator listIterator(){
|
rlm@10
|
231 return reify().listIterator();
|
rlm@10
|
232 }
|
rlm@10
|
233
|
rlm@10
|
234 public ListIterator listIterator(int index){
|
rlm@10
|
235 return reify().listIterator(index);
|
rlm@10
|
236 }
|
rlm@10
|
237
|
rlm@10
|
238 public Object get(int index){
|
rlm@10
|
239 return RT.nth(this, index);
|
rlm@10
|
240 }
|
rlm@10
|
241
|
rlm@10
|
242 public void add(int index, Object element){
|
rlm@10
|
243 throw new UnsupportedOperationException();
|
rlm@10
|
244 }
|
rlm@10
|
245
|
rlm@10
|
246 public boolean addAll(int index, Collection c){
|
rlm@10
|
247 throw new UnsupportedOperationException();
|
rlm@10
|
248 }
|
rlm@10
|
249
|
rlm@10
|
250
|
rlm@10
|
251 }
|