OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 part of dart.core; | |
6 | |
7 /** | |
8 * An indexed sequence of elements of the same type. | |
9 * | |
10 * This is a primitive interface that any finite integer-indexable | |
11 * sequence can implement. | |
12 * It is intended for data structures where access by index is | |
13 * the most efficient way to access the data. | |
14 */ | |
15 abstract class Sequence<E> { | |
16 /** | |
17 * The limit of valid indices of the sequence. | |
18 * | |
19 * The length getter should be efficient. | |
20 */ | |
21 int get length; | |
22 | |
23 /** | |
24 * Returns the value at the given [index]. | |
25 * | |
26 * Valid indices must be in the range [:0..length - 1:]. | |
27 * The lookup operator should be efficient. | |
28 */ | |
29 E operator[](int index); | |
30 } | |
31 | |
32 /** | |
33 * A skeleton class for a [Collection] that is also a [Sequence]. | |
34 */ | |
35 abstract class SequenceCollection<E> implements Collection<E>, Sequence<E> { | |
36 // The class is intended for use as a mixin as well. | |
37 | |
38 Iterator<E> iterator() => new SequenceIterator(sequence); | |
39 | |
40 void forEach(f(E element)) { | |
41 for (int i = 0; i < this.length; i++) f(this[i]); | |
42 } | |
43 | |
44 Collection map(f(E element)) { | |
45 List result = new List(); | |
46 for (int i = 0; i < this.length; i++) { | |
47 result.add(f(this[i])); | |
48 } | |
49 return result; | |
50 } | |
51 | |
52 bool contains(E value) { | |
53 for (int i = 0; i < sequence.length; i++) { | |
54 if (sequence[i] == value) return true; | |
55 } | |
56 return false; | |
57 } | |
58 | |
59 reduce(initialValue, combine(previousValue, E element)) { | |
60 var value = initialValue; | |
61 for (int i = 0; i < this.length; i++) { | |
62 value = combine(value, this[i]); | |
63 } | |
64 return value; | |
65 } | |
66 | |
67 Collection<E> filter(bool f(E element)) { | |
68 List<E> result = <E>[]; | |
69 for (int i = 0; i < this.length; i++) { | |
70 E element = this[i]; | |
71 if (f(element)) result.add(element); | |
72 } | |
73 return result; | |
74 } | |
75 | |
76 bool every(bool f(E element)) { | |
77 for (int i = 0; i < this.length; i++) { | |
78 if (!f(this[i])) return false; | |
79 } | |
80 return true; | |
81 } | |
82 | |
83 bool some(bool f(E element)) { | |
84 for (int i = 0; i < this.length; i++) { | |
85 if (f(this[i])) return true; | |
86 } | |
87 return false; | |
88 } | |
89 | |
90 bool get isEmpty { | |
91 return this.length == 0; | |
92 } | |
93 } | |
94 | |
95 | |
96 /** | |
97 * An unmodifiable [List] backed by a [Sequence]. | |
98 */ | |
99 class SequenceList<E> extends SequenceCollection<E> implements List<E> { | |
100 Sequence<E> sequence; | |
101 SequenceList(this.sequence); | |
102 | |
103 int get length => sequence.length; | |
104 | |
105 E operator[](int index) => sequence[index]; | |
106 | |
107 int indexOf(E value, [int start = 0]) { | |
108 for (int i = start; i < sequence.length; i++) { | |
109 if (sequence[i] == value) return i; | |
110 } | |
111 return -1; | |
112 } | |
113 | |
114 int lastIndexOf(E value, [int start]) { | |
115 if (start == null) start = sequence.length - 1; | |
116 for (int i = start; i >= 0; i--) { | |
117 if (sequence[i] == value) return i; | |
118 } | |
119 return -1; | |
120 } | |
121 | |
122 E get first => sequence[0]; | |
123 E get last => sequence[sequence.length - 1]; | |
124 | |
125 List<E> getRange(int start, int length) { | |
126 List<E> result = <E>[]; | |
127 for (int i = 0; i < length; i++) { | |
128 result.add(sequence[start + i]); | |
129 } | |
130 return result; | |
131 } | |
132 | |
133 void operator []=(int index, E value) { | |
134 throw new UnsupportedError( | |
135 "Cannot modify an unmodifiable list"); | |
136 } | |
137 | |
138 void set length(int newLength) { | |
139 throw new UnsupportedError( | |
140 "Cannot change the length of an unmodifiable list"); | |
141 } | |
142 | |
143 void add(E value) { | |
144 throw new UnsupportedError( | |
145 "Cannot add to an unmodifiable list"); | |
146 } | |
147 | |
148 void addLast(E value) { | |
149 throw new UnsupportedError( | |
150 "Cannot add to an unmodifiable list"); | |
151 } | |
152 | |
153 void addAll(Collection<E> collection) { | |
154 throw new UnsupportedError( | |
155 "Cannot add to an unmodifiable list"); | |
156 } | |
157 | |
158 void sort([int compare(E a, E b)]) { | |
159 throw new UnsupportedError( | |
160 "Cannot modify an unmodifiable list"); | |
161 } | |
162 | |
163 void clear() { | |
164 throw new UnsupportedError( | |
165 "Cannot clear an unmodifiable list"); | |
166 } | |
167 | |
168 E removeAt(int index) { | |
169 throw new UnsupportedError( | |
170 "Cannot remove in an unmodifiable list"); | |
171 } | |
172 | |
173 E removeLast() { | |
174 throw new UnsupportedError( | |
175 "Cannot remove in an unmodifiable list"); | |
176 } | |
177 | |
178 void setRange(int start, int length, List<E> from, [int startFrom]) { | |
179 throw new UnsupportedError( | |
180 "Cannot modify an unmodifiable list"); | |
181 } | |
182 | |
183 void removeRange(int start, int length) { | |
184 throw new UnsupportedError( | |
185 "Cannot remove in an unmodifiable list"); | |
186 } | |
187 | |
188 void insertRange(int start, int length, [E initialValue]) { | |
189 throw new UnsupportedError( | |
190 "Cannot insert range in an unmodifiable list"); | |
191 } | |
192 } | |
193 | |
194 /** | |
195 * Iterates over a [Sequence] in growing index order. | |
196 */ | |
197 class SequenceIterator<E> implements Iterator<E> { | |
198 Sequence<E> _sequence; | |
199 int _position; | |
200 SequenceIterator(this._sequence) : _position = 0; | |
201 bool get hasNext => _position < _sequence.length; | |
202 E next() { | |
203 if (hasNext) return _sequence[_position++]; | |
204 throw new StateError("No more elements"); | |
205 } | |
206 } | |
207 | |
OLD | NEW |