| Index: sdk/lib/collection/iterable.dart
|
| diff --git a/sdk/lib/collection/iterable.dart b/sdk/lib/collection/iterable.dart
|
| index 329068244596f292d2c552e5d94d87d93ebb717f..14af73c69e42cee5f2898609fd3c964f1ef2ed40 100644
|
| --- a/sdk/lib/collection/iterable.dart
|
| +++ b/sdk/lib/collection/iterable.dart
|
| @@ -90,7 +90,7 @@ abstract class IterableMixin<E> implements Iterable<E> {
|
| Set<E> toSet() => new Set<E>.from(this);
|
|
|
| int get length {
|
| - assert(this is! EfficientLength);
|
| + assert(this is! EfficientLengthIterable);
|
| int count = 0;
|
| Iterator it = iterator;
|
| while (it.moveNext()) {
|
| @@ -397,3 +397,34 @@ void _iterablePartsToStrings(Iterable iterable, List parts) {
|
| parts.add(penultimateString);
|
| parts.add(ultimateString);
|
| }
|
| +
|
| +
|
| +/**
|
| + * Marker interface for [Iterable] implementations that have an efficient
|
| + * [length] getter.
|
| + *
|
| + * An iterable implementing this interface should have an "efficient"
|
| + * implementation of `length` that doesn't trigger iteration of the
|
| + * iterable. Being efficient doesn't necessarily require being constant
|
| + * time, but should at least attempt to have have execution time that is
|
| + * better than linear in the elements of the iterable.
|
| + *
|
| + * Methods that worry about reading the length of an `Iterable` because it
|
| + * may be inefficient or may trigger side-effects, or may even never complete,
|
| + * can first check if the iterable `is EfficientLengthIterableIterable`,
|
| + * and if so, use [length] without those concerns.
|
| + *
|
| + * The `EfficientLengthIterable` type should never be used as an API type
|
| + * assertion - neither as argument type or return type of a function.
|
| + * Always use [Iterable] for the type and just document the performance if it
|
| + * is relevant. This avoids needlessly restricting the values that can be used.
|
| + */
|
| +abstract class EfficientLengthIterable<T> implements Iterable<T> {
|
| + /**
|
| + * Returns the number of elements in the iterable.
|
| + *
|
| + * This is an efficient operation that doesn't iterate through
|
| + * the elements.
|
| + */
|
| + int get length;
|
| +}
|
|
|