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 package clojure.lang;
|
rlm@10
|
12
|
rlm@10
|
13 import java.io.Serializable;
|
rlm@10
|
14 import java.util.*;
|
rlm@10
|
15
|
rlm@10
|
16 public class PersistentList extends ASeq implements IPersistentList, IReduce, List, Counted {
|
rlm@10
|
17
|
rlm@10
|
18 private final Object _first;
|
rlm@10
|
19 private final IPersistentList _rest;
|
rlm@10
|
20 private final int _count;
|
rlm@10
|
21
|
rlm@10
|
22 public static IFn creator = new RestFn(){
|
rlm@10
|
23 final public int getRequiredArity(){
|
rlm@10
|
24 return 0;
|
rlm@10
|
25 }
|
rlm@10
|
26
|
rlm@10
|
27 final protected Object doInvoke(Object args) throws Exception{
|
rlm@10
|
28 if(args instanceof ArraySeq)
|
rlm@10
|
29 {
|
rlm@10
|
30 Object[] argsarray = (Object[]) ((ArraySeq) args).array;
|
rlm@10
|
31 IPersistentList ret = EMPTY;
|
rlm@10
|
32 for(int i = argsarray.length - 1; i >= 0; --i)
|
rlm@10
|
33 ret = (IPersistentList) ret.cons(argsarray[i]);
|
rlm@10
|
34 return ret;
|
rlm@10
|
35 }
|
rlm@10
|
36 LinkedList list = new LinkedList();
|
rlm@10
|
37 for(ISeq s = RT.seq(args); s != null; s = s.next())
|
rlm@10
|
38 list.add(s.first());
|
rlm@10
|
39 return create(list);
|
rlm@10
|
40 }
|
rlm@10
|
41
|
rlm@10
|
42 public IObj withMeta(IPersistentMap meta){
|
rlm@10
|
43 throw new UnsupportedOperationException();
|
rlm@10
|
44 }
|
rlm@10
|
45
|
rlm@10
|
46 public IPersistentMap meta(){
|
rlm@10
|
47 return null;
|
rlm@10
|
48 }
|
rlm@10
|
49 };
|
rlm@10
|
50
|
rlm@10
|
51 final public static EmptyList EMPTY = new EmptyList(null);
|
rlm@10
|
52
|
rlm@10
|
53 public PersistentList(Object first){
|
rlm@10
|
54 this._first = first;
|
rlm@10
|
55 this._rest = null;
|
rlm@10
|
56
|
rlm@10
|
57 this._count = 1;
|
rlm@10
|
58 }
|
rlm@10
|
59
|
rlm@10
|
60 PersistentList(IPersistentMap meta, Object _first, IPersistentList _rest, int _count){
|
rlm@10
|
61 super(meta);
|
rlm@10
|
62 this._first = _first;
|
rlm@10
|
63 this._rest = _rest;
|
rlm@10
|
64 this._count = _count;
|
rlm@10
|
65 }
|
rlm@10
|
66
|
rlm@10
|
67 public static IPersistentList create(List init){
|
rlm@10
|
68 IPersistentList ret = EMPTY;
|
rlm@10
|
69 for(ListIterator i = init.listIterator(init.size()); i.hasPrevious();)
|
rlm@10
|
70 {
|
rlm@10
|
71 ret = (IPersistentList) ret.cons(i.previous());
|
rlm@10
|
72 }
|
rlm@10
|
73 return ret;
|
rlm@10
|
74 }
|
rlm@10
|
75
|
rlm@10
|
76 public Object first(){
|
rlm@10
|
77 return _first;
|
rlm@10
|
78 }
|
rlm@10
|
79
|
rlm@10
|
80 public ISeq next(){
|
rlm@10
|
81 if(_count == 1)
|
rlm@10
|
82 return null;
|
rlm@10
|
83 return (ISeq) _rest;
|
rlm@10
|
84 }
|
rlm@10
|
85
|
rlm@10
|
86 public Object peek(){
|
rlm@10
|
87 return first();
|
rlm@10
|
88 }
|
rlm@10
|
89
|
rlm@10
|
90 public IPersistentList pop(){
|
rlm@10
|
91 if(_rest == null)
|
rlm@10
|
92 return EMPTY.withMeta(_meta);
|
rlm@10
|
93 return _rest;
|
rlm@10
|
94 }
|
rlm@10
|
95
|
rlm@10
|
96 public int count(){
|
rlm@10
|
97 return _count;
|
rlm@10
|
98 }
|
rlm@10
|
99
|
rlm@10
|
100 public PersistentList cons(Object o){
|
rlm@10
|
101 return new PersistentList(meta(), o, this, _count + 1);
|
rlm@10
|
102 }
|
rlm@10
|
103
|
rlm@10
|
104 public IPersistentCollection empty(){
|
rlm@10
|
105 return EMPTY.withMeta(meta());
|
rlm@10
|
106 }
|
rlm@10
|
107
|
rlm@10
|
108 public PersistentList withMeta(IPersistentMap meta){
|
rlm@10
|
109 if(meta != _meta)
|
rlm@10
|
110 return new PersistentList(meta, _first, _rest, _count);
|
rlm@10
|
111 return this;
|
rlm@10
|
112 }
|
rlm@10
|
113
|
rlm@10
|
114 public Object reduce(IFn f) throws Exception{
|
rlm@10
|
115 Object ret = first();
|
rlm@10
|
116 for(ISeq s = next(); s != null; s = s.next())
|
rlm@10
|
117 ret = f.invoke(ret, s.first());
|
rlm@10
|
118 return ret;
|
rlm@10
|
119 }
|
rlm@10
|
120
|
rlm@10
|
121 public Object reduce(IFn f, Object start) throws Exception{
|
rlm@10
|
122 Object ret = f.invoke(start, first());
|
rlm@10
|
123 for(ISeq s = next(); s != null; s = s.next())
|
rlm@10
|
124 ret = f.invoke(ret, s.first());
|
rlm@10
|
125 return ret;
|
rlm@10
|
126 }
|
rlm@10
|
127
|
rlm@10
|
128
|
rlm@10
|
129 static class EmptyList extends Obj implements IPersistentList, List, ISeq, Counted{
|
rlm@10
|
130
|
rlm@10
|
131 public int hashCode(){
|
rlm@10
|
132 return 1;
|
rlm@10
|
133 }
|
rlm@10
|
134
|
rlm@10
|
135 public boolean equals(Object o) {
|
rlm@10
|
136 return (o instanceof Sequential || o instanceof List) && RT.seq(o) == null;
|
rlm@10
|
137 }
|
rlm@10
|
138
|
rlm@10
|
139 public boolean equiv(Object o){
|
rlm@10
|
140 return equals(o);
|
rlm@10
|
141 }
|
rlm@10
|
142
|
rlm@10
|
143 EmptyList(IPersistentMap meta){
|
rlm@10
|
144 super(meta);
|
rlm@10
|
145 }
|
rlm@10
|
146
|
rlm@10
|
147 public Object first() {
|
rlm@10
|
148 return null;
|
rlm@10
|
149 }
|
rlm@10
|
150
|
rlm@10
|
151 public ISeq next() {
|
rlm@10
|
152 return null;
|
rlm@10
|
153 }
|
rlm@10
|
154
|
rlm@10
|
155 public ISeq more() {
|
rlm@10
|
156 return this;
|
rlm@10
|
157 }
|
rlm@10
|
158
|
rlm@10
|
159 public PersistentList cons(Object o){
|
rlm@10
|
160 return new PersistentList(meta(), o, null, 1);
|
rlm@10
|
161 }
|
rlm@10
|
162
|
rlm@10
|
163 public IPersistentCollection empty(){
|
rlm@10
|
164 return this;
|
rlm@10
|
165 }
|
rlm@10
|
166
|
rlm@10
|
167 public EmptyList withMeta(IPersistentMap meta){
|
rlm@10
|
168 if(meta != meta())
|
rlm@10
|
169 return new EmptyList(meta);
|
rlm@10
|
170 return this;
|
rlm@10
|
171 }
|
rlm@10
|
172
|
rlm@10
|
173 public Object peek(){
|
rlm@10
|
174 return null;
|
rlm@10
|
175 }
|
rlm@10
|
176
|
rlm@10
|
177 public IPersistentList pop(){
|
rlm@10
|
178 throw new IllegalStateException("Can't pop empty list");
|
rlm@10
|
179 }
|
rlm@10
|
180
|
rlm@10
|
181 public int count(){
|
rlm@10
|
182 return 0;
|
rlm@10
|
183 }
|
rlm@10
|
184
|
rlm@10
|
185 public ISeq seq(){
|
rlm@10
|
186 return null;
|
rlm@10
|
187 }
|
rlm@10
|
188
|
rlm@10
|
189
|
rlm@10
|
190 public int size(){
|
rlm@10
|
191 return 0;
|
rlm@10
|
192 }
|
rlm@10
|
193
|
rlm@10
|
194 public boolean isEmpty(){
|
rlm@10
|
195 return true;
|
rlm@10
|
196 }
|
rlm@10
|
197
|
rlm@10
|
198 public boolean contains(Object o){
|
rlm@10
|
199 return false;
|
rlm@10
|
200 }
|
rlm@10
|
201
|
rlm@10
|
202 public Iterator iterator(){
|
rlm@10
|
203 return new Iterator(){
|
rlm@10
|
204
|
rlm@10
|
205 public boolean hasNext(){
|
rlm@10
|
206 return false;
|
rlm@10
|
207 }
|
rlm@10
|
208
|
rlm@10
|
209 public Object next(){
|
rlm@10
|
210 throw new NoSuchElementException();
|
rlm@10
|
211 }
|
rlm@10
|
212
|
rlm@10
|
213 public void remove(){
|
rlm@10
|
214 throw new UnsupportedOperationException();
|
rlm@10
|
215 }
|
rlm@10
|
216 };
|
rlm@10
|
217 }
|
rlm@10
|
218
|
rlm@10
|
219 public Object[] toArray(){
|
rlm@10
|
220 return RT.EMPTY_ARRAY;
|
rlm@10
|
221 }
|
rlm@10
|
222
|
rlm@10
|
223 public boolean add(Object o){
|
rlm@10
|
224 throw new UnsupportedOperationException();
|
rlm@10
|
225 }
|
rlm@10
|
226
|
rlm@10
|
227 public boolean remove(Object o){
|
rlm@10
|
228 throw new UnsupportedOperationException();
|
rlm@10
|
229 }
|
rlm@10
|
230
|
rlm@10
|
231 public boolean addAll(Collection collection){
|
rlm@10
|
232 throw new UnsupportedOperationException();
|
rlm@10
|
233 }
|
rlm@10
|
234
|
rlm@10
|
235 public void clear(){
|
rlm@10
|
236 throw new UnsupportedOperationException();
|
rlm@10
|
237 }
|
rlm@10
|
238
|
rlm@10
|
239 public boolean retainAll(Collection collection){
|
rlm@10
|
240 throw new UnsupportedOperationException();
|
rlm@10
|
241 }
|
rlm@10
|
242
|
rlm@10
|
243 public boolean removeAll(Collection collection){
|
rlm@10
|
244 throw new UnsupportedOperationException();
|
rlm@10
|
245 }
|
rlm@10
|
246
|
rlm@10
|
247 public boolean containsAll(Collection collection){
|
rlm@10
|
248 return collection.isEmpty();
|
rlm@10
|
249 }
|
rlm@10
|
250
|
rlm@10
|
251 public Object[] toArray(Object[] objects){
|
rlm@10
|
252 if(objects.length > 0)
|
rlm@10
|
253 objects[0] = null;
|
rlm@10
|
254 return objects;
|
rlm@10
|
255 }
|
rlm@10
|
256
|
rlm@10
|
257 //////////// List stuff /////////////////
|
rlm@10
|
258 private List reify(){
|
rlm@10
|
259 return Collections.unmodifiableList(new ArrayList(this));
|
rlm@10
|
260 }
|
rlm@10
|
261
|
rlm@10
|
262 public List subList(int fromIndex, int toIndex){
|
rlm@10
|
263 return reify().subList(fromIndex, toIndex);
|
rlm@10
|
264 }
|
rlm@10
|
265
|
rlm@10
|
266 public Object set(int index, Object element){
|
rlm@10
|
267 throw new UnsupportedOperationException();
|
rlm@10
|
268 }
|
rlm@10
|
269
|
rlm@10
|
270 public Object remove(int index){
|
rlm@10
|
271 throw new UnsupportedOperationException();
|
rlm@10
|
272 }
|
rlm@10
|
273
|
rlm@10
|
274 public int indexOf(Object o){
|
rlm@10
|
275 ISeq s = seq();
|
rlm@10
|
276 for(int i = 0; s != null; s = s.next(), i++)
|
rlm@10
|
277 {
|
rlm@10
|
278 if(Util.equiv(s.first(), o))
|
rlm@10
|
279 return i;
|
rlm@10
|
280 }
|
rlm@10
|
281 return -1;
|
rlm@10
|
282 }
|
rlm@10
|
283
|
rlm@10
|
284 public int lastIndexOf(Object o){
|
rlm@10
|
285 return reify().lastIndexOf(o);
|
rlm@10
|
286 }
|
rlm@10
|
287
|
rlm@10
|
288 public ListIterator listIterator(){
|
rlm@10
|
289 return reify().listIterator();
|
rlm@10
|
290 }
|
rlm@10
|
291
|
rlm@10
|
292 public ListIterator listIterator(int index){
|
rlm@10
|
293 return reify().listIterator(index);
|
rlm@10
|
294 }
|
rlm@10
|
295
|
rlm@10
|
296 public Object get(int index){
|
rlm@10
|
297 return RT.nth(this, index);
|
rlm@10
|
298 }
|
rlm@10
|
299
|
rlm@10
|
300 public void add(int index, Object element){
|
rlm@10
|
301 throw new UnsupportedOperationException();
|
rlm@10
|
302 }
|
rlm@10
|
303
|
rlm@10
|
304 public boolean addAll(int index, Collection c){
|
rlm@10
|
305 throw new UnsupportedOperationException();
|
rlm@10
|
306 }
|
rlm@10
|
307
|
rlm@10
|
308
|
rlm@10
|
309 }
|
rlm@10
|
310
|
rlm@10
|
311 }
|