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; |
+} |