Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: sdk/lib/collection/iterable.dart

Issue 2754013002: Format all dart: library files (Closed)
Patch Set: Format all dart: library files Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sdk/lib/collection/hash_set.dart ('k') | sdk/lib/collection/linked_hash_map.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of dart.collection; 5 part of dart.collection;
6 6
7 /** 7 /**
8 * This [Iterable] mixin implements all [Iterable] members except `iterator`. 8 * This [Iterable] mixin implements all [Iterable] members except `iterator`.
9 * 9 *
10 * All other methods are implemented in terms of `iterator`. 10 * All other methods are implemented in terms of `iterator`.
11 */ 11 */
12 abstract class IterableMixin<E> implements Iterable<E> { 12 abstract class IterableMixin<E> implements Iterable<E> {
13 // This class has methods copied verbatim into: 13 // This class has methods copied verbatim into:
14 // - IterableBase 14 // - IterableBase
15 // - SetMixin 15 // - SetMixin
16 // If changing a method here, also change the other copies. 16 // If changing a method here, also change the other copies.
17 17
18 Iterable<T> map<T>(T f(E element)) => 18 Iterable<T> map<T>(T f(E element)) => new MappedIterable<E, T>(this, f);
19 new MappedIterable<E, T>(this, f);
20 19
21 Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f); 20 Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
22 21
23 Iterable<T> expand<T>(Iterable<T> f(E element)) => 22 Iterable<T>
24 new ExpandIterable<E, T>(this, f); 23 expand<T>(Iterable<T> f(E element)) => new ExpandIterable<E, T>(this, f);
25 24
26 bool contains(Object element) { 25 bool contains(Object element) {
27 for (E e in this) { 26 for (E e in this) {
28 if (e == element) return true; 27 if (e == element) return true;
29 } 28 }
30 return false; 29 return false;
31 } 30 }
32 31
33 void forEach(void f(E element)) { 32 void forEach(void f(E element)) {
34 for (E element in this) f(element); 33 for (E element in this) f(element);
35 } 34 }
36 35
37 E reduce(E combine(E value, E element)) { 36 E reduce(E combine(E value, E element)) {
38 Iterator<E> iterator = this.iterator; 37 Iterator<E> iterator = this.iterator;
39 if (!iterator.moveNext()) { 38 if (!iterator.moveNext()) {
40 throw IterableElementError.noElement(); 39 throw IterableElementError.noElement();
41 } 40 }
42 E value = iterator.current; 41 E value = iterator.current;
43 while (iterator.moveNext()) { 42 while (iterator.moveNext()) {
44 value = combine(value, iterator.current); 43 value = combine(value, iterator.current);
45 } 44 }
46 return value; 45 return value;
47 } 46 }
48 47
49 T fold<T>(T initialValue, 48 T fold<T>(T initialValue, T combine(T previousValue, E element)) {
50 T combine(T previousValue, E element)) {
51 var value = initialValue; 49 var value = initialValue;
52 for (E element in this) value = combine(value, element); 50 for (E element in this) value = combine(value, element);
53 return value; 51 return value;
54 } 52 }
55 53
56 bool every(bool f(E element)) { 54 bool every(bool f(E element)) {
57 for (E element in this) { 55 for (E element in this) {
58 if (!f(element)) return false; 56 if (!f(element)) return false;
59 } 57 }
60 return true; 58 return true;
(...skipping 17 matching lines...) Expand all
78 return buffer.toString(); 76 return buffer.toString();
79 } 77 }
80 78
81 bool any(bool f(E element)) { 79 bool any(bool f(E element)) {
82 for (E element in this) { 80 for (E element in this) {
83 if (f(element)) return true; 81 if (f(element)) return true;
84 } 82 }
85 return false; 83 return false;
86 } 84 }
87 85
88 List<E> toList({ bool growable: true }) => 86 List<E> toList({bool growable: true}) =>
89 new List<E>.from(this, growable: growable); 87 new List<E>.from(this, growable: growable);
90 88
91 Set<E> toSet() => new Set<E>.from(this); 89 Set<E> toSet() => new Set<E>.from(this);
92 90
93 int get length { 91 int get length {
94 assert(this is! EfficientLengthIterable); 92 assert(this is! EfficientLengthIterable);
95 int count = 0; 93 int count = 0;
96 Iterator it = iterator; 94 Iterator it = iterator;
97 while (it.moveNext()) { 95 while (it.moveNext()) {
98 count++; 96 count++;
(...skipping 30 matching lines...) Expand all
129 } 127 }
130 128
131 E get last { 129 E get last {
132 Iterator<E> it = iterator; 130 Iterator<E> it = iterator;
133 if (!it.moveNext()) { 131 if (!it.moveNext()) {
134 throw IterableElementError.noElement(); 132 throw IterableElementError.noElement();
135 } 133 }
136 E result; 134 E result;
137 do { 135 do {
138 result = it.current; 136 result = it.current;
139 } while(it.moveNext()); 137 } while (it.moveNext());
140 return result; 138 return result;
141 } 139 }
142 140
143 E get single { 141 E get single {
144 Iterator<E> it = iterator; 142 Iterator<E> it = iterator;
145 if (!it.moveNext()) throw IterableElementError.noElement(); 143 if (!it.moveNext()) throw IterableElementError.noElement();
146 E result = it.current; 144 E result = it.current;
147 if (it.moveNext()) throw IterableElementError.tooMany(); 145 if (it.moveNext()) throw IterableElementError.tooMany();
148 return result; 146 return result;
149 } 147 }
150 148
151 E firstWhere(bool test(E value), { E orElse() }) { 149 E firstWhere(bool test(E value), {E orElse()}) {
152 for (E element in this) { 150 for (E element in this) {
153 if (test(element)) return element; 151 if (test(element)) return element;
154 } 152 }
155 if (orElse != null) return orElse(); 153 if (orElse != null) return orElse();
156 throw IterableElementError.noElement(); 154 throw IterableElementError.noElement();
157 } 155 }
158 156
159 E lastWhere(bool test(E value), { E orElse() }) { 157 E lastWhere(bool test(E value), {E orElse()}) {
160 E result = null; 158 E result = null;
161 bool foundMatching = false; 159 bool foundMatching = false;
162 for (E element in this) { 160 for (E element in this) {
163 if (test(element)) { 161 if (test(element)) {
164 result = element; 162 result = element;
165 foundMatching = true; 163 foundMatching = true;
166 } 164 }
167 } 165 }
168 if (foundMatching) return result; 166 if (foundMatching) return result;
169 if (orElse != null) return orElse(); 167 if (orElse != null) return orElse();
(...skipping 20 matching lines...) Expand all
190 if (index is! int) throw new ArgumentError.notNull("index"); 188 if (index is! int) throw new ArgumentError.notNull("index");
191 RangeError.checkNotNegative(index, "index"); 189 RangeError.checkNotNegative(index, "index");
192 int elementIndex = 0; 190 int elementIndex = 0;
193 for (E element in this) { 191 for (E element in this) {
194 if (index == elementIndex) return element; 192 if (index == elementIndex) return element;
195 elementIndex++; 193 elementIndex++;
196 } 194 }
197 throw new RangeError.index(index, this, "index", null, elementIndex); 195 throw new RangeError.index(index, this, "index", null, elementIndex);
198 } 196 }
199 197
200
201 String toString() => IterableBase.iterableToShortString(this, '(', ')'); 198 String toString() => IterableBase.iterableToShortString(this, '(', ')');
202 } 199 }
203 200
204 /** 201 /**
205 * Base class for implementing [Iterable]. 202 * Base class for implementing [Iterable].
206 * 203 *
207 * This class implements all methods of [Iterable] except [Iterable.iterator] 204 * This class implements all methods of [Iterable] except [Iterable.iterator]
208 * in terms of `iterator`. 205 * in terms of `iterator`.
209 */ 206 */
210 abstract class IterableBase<E> extends Iterable<E> { 207 abstract class IterableBase<E> extends Iterable<E> {
211 const IterableBase(); 208 const IterableBase();
212 209
213 /** 210 /**
214 * Convert an `Iterable` to a string like [IterableBase.toString]. 211 * Convert an `Iterable` to a string like [IterableBase.toString].
215 * 212 *
216 * Allows using other delimiters than '(' and ')'. 213 * Allows using other delimiters than '(' and ')'.
217 * 214 *
218 * Handles circular references where converting one of the elements 215 * Handles circular references where converting one of the elements
219 * to a string ends up converting [iterable] to a string again. 216 * to a string ends up converting [iterable] to a string again.
220 */ 217 */
221 static String iterableToShortString(Iterable iterable, 218 static String iterableToShortString(Iterable iterable,
222 [String leftDelimiter = '(', 219 [String leftDelimiter = '(', String rightDelimiter = ')']) {
223 String rightDelimiter = ')']) {
224 if (_isToStringVisiting(iterable)) { 220 if (_isToStringVisiting(iterable)) {
225 if (leftDelimiter == "(" && rightDelimiter == ")") { 221 if (leftDelimiter == "(" && rightDelimiter == ")") {
226 // Avoid creating a new string in the "common" case. 222 // Avoid creating a new string in the "common" case.
227 return "(...)"; 223 return "(...)";
228 } 224 }
229 return "$leftDelimiter...$rightDelimiter"; 225 return "$leftDelimiter...$rightDelimiter";
230 } 226 }
231 List parts = []; 227 List parts = [];
232 _toStringVisiting.add(iterable); 228 _toStringVisiting.add(iterable);
233 try { 229 try {
234 _iterablePartsToStrings(iterable, parts); 230 _iterablePartsToStrings(iterable, parts);
235 } finally { 231 } finally {
236 assert(identical(_toStringVisiting.last, iterable)); 232 assert(identical(_toStringVisiting.last, iterable));
237 _toStringVisiting.removeLast(); 233 _toStringVisiting.removeLast();
238 } 234 }
239 return (new StringBuffer(leftDelimiter) 235 return (new StringBuffer(leftDelimiter)
240 ..writeAll(parts, ", ") 236 ..writeAll(parts, ", ")
241 ..write(rightDelimiter)).toString(); 237 ..write(rightDelimiter))
238 .toString();
242 } 239 }
243 240
244 /** 241 /**
245 * Converts an `Iterable` to a string. 242 * Converts an `Iterable` to a string.
246 * 243 *
247 * Converts each elements to a string, and separates the results by ", ". 244 * Converts each elements to a string, and separates the results by ", ".
248 * Then wraps the result in [leftDelimiter] and [rightDelimiter]. 245 * Then wraps the result in [leftDelimiter] and [rightDelimiter].
249 * 246 *
250 * Unlike [iterableToShortString], this conversion doesn't omit any 247 * Unlike [iterableToShortString], this conversion doesn't omit any
251 * elements or puts any limit on the size of the result. 248 * elements or puts any limit on the size of the result.
252 * 249 *
253 * Handles circular references where converting one of the elements 250 * Handles circular references where converting one of the elements
254 * to a string ends up converting [iterable] to a string again. 251 * to a string ends up converting [iterable] to a string again.
255 */ 252 */
256 static String iterableToFullString(Iterable iterable, 253 static String iterableToFullString(Iterable iterable,
257 [String leftDelimiter = '(', 254 [String leftDelimiter = '(', String rightDelimiter = ')']) {
258 String rightDelimiter = ')']) {
259 if (_isToStringVisiting(iterable)) { 255 if (_isToStringVisiting(iterable)) {
260 return "$leftDelimiter...$rightDelimiter"; 256 return "$leftDelimiter...$rightDelimiter";
261 } 257 }
262 StringBuffer buffer = new StringBuffer(leftDelimiter); 258 StringBuffer buffer = new StringBuffer(leftDelimiter);
263 _toStringVisiting.add(iterable); 259 _toStringVisiting.add(iterable);
264 try { 260 try {
265 buffer.writeAll(iterable, ", "); 261 buffer.writeAll(iterable, ", ");
266 } finally { 262 } finally {
267 assert(identical(_toStringVisiting.last, iterable)); 263 assert(identical(_toStringVisiting.last, iterable));
268 _toStringVisiting.removeLast(); 264 _toStringVisiting.removeLast();
(...skipping 18 matching lines...) Expand all
287 * Convert elments of [iterable] to strings and store them in [parts]. 283 * Convert elments of [iterable] to strings and store them in [parts].
288 */ 284 */
289 void _iterablePartsToStrings(Iterable iterable, List parts) { 285 void _iterablePartsToStrings(Iterable iterable, List parts) {
290 /* 286 /*
291 * This is the complicated part of [iterableToShortString]. 287 * This is the complicated part of [iterableToShortString].
292 * It is extracted as a separate function to avoid having too much code 288 * It is extracted as a separate function to avoid having too much code
293 * inside the try/finally. 289 * inside the try/finally.
294 */ 290 */
295 /// Try to stay below this many characters. 291 /// Try to stay below this many characters.
296 const int LENGTH_LIMIT = 80; 292 const int LENGTH_LIMIT = 80;
293
297 /// Always at least this many elements at the start. 294 /// Always at least this many elements at the start.
298 const int HEAD_COUNT = 3; 295 const int HEAD_COUNT = 3;
296
299 /// Always at least this many elements at the end. 297 /// Always at least this many elements at the end.
300 const int TAIL_COUNT = 2; 298 const int TAIL_COUNT = 2;
299
301 /// Stop iterating after this many elements. Iterables can be infinite. 300 /// Stop iterating after this many elements. Iterables can be infinite.
302 const int MAX_COUNT = 100; 301 const int MAX_COUNT = 100;
303 // Per entry length overhead. It's for ", " for all after the first entry, 302 // Per entry length overhead. It's for ", " for all after the first entry,
304 // and for "(" and ")" for the initial entry. By pure luck, that's the same 303 // and for "(" and ")" for the initial entry. By pure luck, that's the same
305 // number. 304 // number.
306 const int OVERHEAD = 2; 305 const int OVERHEAD = 2;
307 const int ELLIPSIS_SIZE = 3; // "...".length. 306 const int ELLIPSIS_SIZE = 3; // "...".length.
308 307
309 int length = 0; 308 int length = 0;
310 int count = 0; 309 int count = 0;
311 Iterator it = iterable.iterator; 310 Iterator it = iterable.iterator;
312 // Initial run of elements, at least HEAD_COUNT, and then continue until 311 // Initial run of elements, at least HEAD_COUNT, and then continue until
313 // passing at most LENGTH_LIMIT characters. 312 // passing at most LENGTH_LIMIT characters.
314 while (length < LENGTH_LIMIT || count < HEAD_COUNT) { 313 while (length < LENGTH_LIMIT || count < HEAD_COUNT) {
315 if (!it.moveNext()) return; 314 if (!it.moveNext()) return;
316 String next = "${it.current}"; 315 String next = "${it.current}";
317 parts.add(next); 316 parts.add(next);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 count++; 351 count++;
353 if (count > MAX_COUNT) { 352 if (count > MAX_COUNT) {
354 // If we haven't found the end before MAX_COUNT, give up. 353 // If we haven't found the end before MAX_COUNT, give up.
355 // This cannot happen in the code above because each entry 354 // This cannot happen in the code above because each entry
356 // increases length by at least two, so there is no way to 355 // increases length by at least two, so there is no way to
357 // visit more than ~40 elements before this loop. 356 // visit more than ~40 elements before this loop.
358 357
359 // Remove any surplus elements until length, including ", ...)", 358 // Remove any surplus elements until length, including ", ...)",
360 // is at most LENGTH_LIMIT. 359 // is at most LENGTH_LIMIT.
361 while (length > LENGTH_LIMIT - ELLIPSIS_SIZE - OVERHEAD && 360 while (length > LENGTH_LIMIT - ELLIPSIS_SIZE - OVERHEAD &&
362 count > HEAD_COUNT) { 361 count > HEAD_COUNT) {
363 length -= parts.removeLast().length + OVERHEAD; 362 length -= parts.removeLast().length + OVERHEAD;
364 count--; 363 count--;
365 } 364 }
366 parts.add("..."); 365 parts.add("...");
367 return; 366 return;
368 } 367 }
369 } 368 }
370 penultimateString = "$penultimate"; 369 penultimateString = "$penultimate";
371 ultimateString = "$ultimate"; 370 ultimateString = "$ultimate";
372 length += 371 length += ultimateString.length + penultimateString.length + 2 * OVERHEAD;
373 ultimateString.length + penultimateString.length + 2 * OVERHEAD;
374 } 372 }
375 } 373 }
376 374
377 // If there is a gap between the initial run and the last two, 375 // If there is a gap between the initial run and the last two,
378 // prepare to add an ellipsis. 376 // prepare to add an ellipsis.
379 String elision = null; 377 String elision = null;
380 if (count > parts.length + TAIL_COUNT) { 378 if (count > parts.length + TAIL_COUNT) {
381 elision = "..."; 379 elision = "...";
382 length += ELLIPSIS_SIZE + OVERHEAD; 380 length += ELLIPSIS_SIZE + OVERHEAD;
383 } 381 }
384 382
385 // If the last two elements were very long, and we have more than 383 // If the last two elements were very long, and we have more than
386 // HEAD_COUNT elements in the initial run, drop some to make room for 384 // HEAD_COUNT elements in the initial run, drop some to make room for
387 // the last two. 385 // the last two.
388 while (length > LENGTH_LIMIT && parts.length > HEAD_COUNT) { 386 while (length > LENGTH_LIMIT && parts.length > HEAD_COUNT) {
389 length -= parts.removeLast().length + OVERHEAD; 387 length -= parts.removeLast().length + OVERHEAD;
390 if (elision == null) { 388 if (elision == null) {
391 elision = "..."; 389 elision = "...";
392 length += ELLIPSIS_SIZE + OVERHEAD; 390 length += ELLIPSIS_SIZE + OVERHEAD;
393 } 391 }
394 } 392 }
395 if (elision != null) { 393 if (elision != null) {
396 parts.add(elision); 394 parts.add(elision);
397 } 395 }
398 parts.add(penultimateString); 396 parts.add(penultimateString);
399 parts.add(ultimateString); 397 parts.add(ultimateString);
400 } 398 }
OLDNEW
« no previous file with comments | « sdk/lib/collection/hash_set.dart ('k') | sdk/lib/collection/linked_hash_map.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698