mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:27:39 +00:00
Make EfficientLength public, as EfficientLengthIterable.
R=iposva@google.com, sgjesse@google.com Review URL: https://codereview.chromium.org//1104063002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@45556 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
a79c250c13
commit
92c526b2a2
|
@ -33,7 +33,7 @@ patch class List<E> {
|
|||
}
|
||||
|
||||
/* patch */ factory List.from(Iterable elements, { bool growable: true }) {
|
||||
if (elements is EfficientLength) {
|
||||
if (elements is EfficientLengthIterable) {
|
||||
int length = elements.length;
|
||||
var list = growable ? new _GrowableList<E>(length) : new _List<E>(length);
|
||||
int i = 0;
|
||||
|
|
|
@ -432,8 +432,8 @@ class _HashMapEntry {
|
|||
_HashMapEntry(this.key, this.value, this.hashCode, this.next);
|
||||
}
|
||||
|
||||
abstract class _HashMapIterable<E> extends IterableBase<E>
|
||||
implements EfficientLength {
|
||||
abstract class _HashMapIterable<E> extends Iterable<E>
|
||||
implements EfficientLengthIterable<E> {
|
||||
final HashMap _map;
|
||||
_HashMapIterable(this._map);
|
||||
int get length => _map.length;
|
||||
|
@ -835,8 +835,8 @@ class _LinkedHashMapEntry extends _HashMapEntry {
|
|||
}
|
||||
}
|
||||
|
||||
class _LinkedHashMapKeyIterable<K> extends IterableBase<K>
|
||||
implements EfficientLength {
|
||||
class _LinkedHashMapKeyIterable<K> extends Iterable<K>
|
||||
implements EfficientLengthIterable<K> {
|
||||
LinkedHashMap<K, dynamic> _map;
|
||||
_LinkedHashMapKeyIterable(this._map);
|
||||
Iterator<K> get iterator => new _LinkedHashMapKeyIterator<K>(_map);
|
||||
|
@ -847,8 +847,8 @@ class _LinkedHashMapKeyIterable<K> extends IterableBase<K>
|
|||
Set<K> toSet() => _map._newKeySet()..addAll(this);
|
||||
}
|
||||
|
||||
class _LinkedHashMapValueIterable<V> extends IterableBase<V>
|
||||
implements EfficientLength {
|
||||
class _LinkedHashMapValueIterable<V> extends Iterable<V>
|
||||
implements EfficientLengthIterable<V> {
|
||||
LinkedHashMap<dynamic, V> _map;
|
||||
_LinkedHashMapValueIterable(this._map);
|
||||
Iterator<V> get iterator => new _LinkedHashMapValueIterator<V>(_map);
|
||||
|
|
|
@ -157,7 +157,7 @@ class _GrowableList<T> extends ListBase<T> {
|
|||
(cid == ClassID.cidArray) ||
|
||||
(cid == ClassID.cidGrowableObjectArray) ||
|
||||
(cid == ClassID.cidImmutableArray);
|
||||
if (isVMList || (iterable is EfficientLength)) {
|
||||
if (isVMList || (iterable is EfficientLengthIterable)) {
|
||||
var cap = _capacity;
|
||||
// Pregrow if we know iterable.length.
|
||||
var iterLen = iterable.length;
|
||||
|
|
|
@ -84,8 +84,8 @@ class ImmutableMap<K, V> implements Map<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
class _ImmutableMapKeyIterable<E> extends IterableBase<E>
|
||||
implements EfficientLength {
|
||||
class _ImmutableMapKeyIterable<E> extends Iterable<E>
|
||||
implements EfficientLengthIterable<E> {
|
||||
final ImmutableMap _map;
|
||||
_ImmutableMapKeyIterable(this._map);
|
||||
|
||||
|
@ -96,8 +96,8 @@ class _ImmutableMapKeyIterable<E> extends IterableBase<E>
|
|||
int get length => _map.length;
|
||||
}
|
||||
|
||||
class _ImmutableMapValueIterable<E> extends IterableBase<E>
|
||||
implements EfficientLength {
|
||||
class _ImmutableMapValueIterable<E> extends Iterable<E>
|
||||
implements EfficientLengthIterable<E> {
|
||||
final ImmutableMap _map;
|
||||
_ImmutableMapValueIterable(this._map);
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ class _StringBase {
|
|||
static String _createStringFromIterable(Iterable<int> charCodes,
|
||||
int start, int end) {
|
||||
// Treat charCodes as Iterable.
|
||||
if (charCodes is EfficientLength) {
|
||||
if (charCodes is EfficientLengthIterable) {
|
||||
int length = charCodes.length;
|
||||
end = RangeError.checkValidRange(start, end, length);
|
||||
List charCodeList = new List.from(charCodes.take(end).skip(start),
|
||||
|
|
|
@ -2147,7 +2147,6 @@ TEST_CASE(Debug_GetSupertype) {
|
|||
Dart_Handle object_name = Dart_NewStringFromCString("Object");
|
||||
Dart_Handle int_name = Dart_NewStringFromCString("int");
|
||||
Dart_Handle set_name = Dart_NewStringFromCString("Set");
|
||||
Dart_Handle iterable_name = Dart_NewStringFromCString("Iterable");
|
||||
Dart_Handle list_name = Dart_NewStringFromCString("List");
|
||||
|
||||
Dart_Handle object_type = Dart_GetType(core_lib, object_name, 0, NULL);
|
||||
|
@ -2208,7 +2207,7 @@ TEST_CASE(Debug_GetSupertype) {
|
|||
{
|
||||
Dart_Handle set_type = Dart_GetType(core_lib, set_name, 0, NULL);
|
||||
Dart_Handle super_type = Dart_GetSupertype(set_type);
|
||||
Dart_Handle iterable_type = Dart_GetType(core_lib, iterable_name, 0, NULL);
|
||||
Dart_Handle iterable_type = Dart_GetType(core_lib, object_name, 0, NULL);
|
||||
const Type& expected_type = Api::UnwrapTypeHandle(isolate, iterable_type);
|
||||
const Type& actual_type = Api::UnwrapTypeHandle(isolate, super_type);
|
||||
EXPECT(expected_type.raw() == actual_type.raw());
|
||||
|
|
|
@ -430,7 +430,7 @@ class _CustomHashMap<K, V> extends _HashMap<K, V> {
|
|||
}
|
||||
|
||||
class HashMapKeyIterable<E> extends Iterable<E>
|
||||
implements EfficientLength {
|
||||
implements EfficientLengthIterable<E> {
|
||||
final _map;
|
||||
HashMapKeyIterable(this._map);
|
||||
|
||||
|
|
|
@ -23,8 +23,7 @@ abstract class ConstantMap<K, V> implements Map<K, V> {
|
|||
void addAll(Map<K, V> other) => _throwUnmodifiable();
|
||||
}
|
||||
|
||||
class ConstantStringMap<K, V> extends ConstantMap<K, V>
|
||||
implements _symbol_dev.EfficientLength {
|
||||
class ConstantStringMap<K, V> extends ConstantMap<K, V> {
|
||||
|
||||
// This constructor is not used. The instantiation is shortcut by the
|
||||
// compiler. It is here to make the uninitialized final fields legal.
|
||||
|
|
|
@ -125,7 +125,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
|
|||
void insertAll(int index, Iterable<E> iterable) {
|
||||
checkGrowable('insertAll');
|
||||
RangeError.checkValueInInterval(index, 0, this.length, "index");
|
||||
if (iterable is! EfficientLength) {
|
||||
if (iterable is! EfficientLengthIterable) {
|
||||
iterable = iterable.toList();
|
||||
}
|
||||
int insertionLength = iterable.length;
|
||||
|
@ -440,7 +440,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
|
|||
void replaceRange(int start, int end, Iterable<E> replacement) {
|
||||
checkGrowable('replace range');
|
||||
RangeError.checkValidRange(start, end, this.length);
|
||||
if (replacement is! EfficientLength) {
|
||||
if (replacement is! EfficientLengthIterable) {
|
||||
replacement = replacement.toList();
|
||||
}
|
||||
int removeLength = end - start;
|
||||
|
|
|
@ -68,7 +68,7 @@ import 'dart:_foreign_helper' show
|
|||
|
||||
import 'dart:_interceptors';
|
||||
import 'dart:_internal' as _symbol_dev;
|
||||
import 'dart:_internal' show EfficientLength, MappedIterable;
|
||||
import 'dart:_internal' show MappedIterable;
|
||||
|
||||
import 'dart:_native_typed_data';
|
||||
|
||||
|
|
|
@ -370,7 +370,7 @@ class LinkedHashMapCell {
|
|||
}
|
||||
|
||||
class LinkedHashMapKeyIterable<E> extends Iterable<E>
|
||||
implements EfficientLength {
|
||||
implements EfficientLengthIterable<E> {
|
||||
final _map;
|
||||
LinkedHashMapKeyIterable(this._map);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -389,7 +389,7 @@ abstract class ListMixin<E> implements List<E> {
|
|||
|
||||
void replaceRange(int start, int end, Iterable<E> newContents) {
|
||||
RangeError.checkValidRange(start, end, this.length);
|
||||
if (newContents is! EfficientLength) {
|
||||
if (newContents is! EfficientLengthIterable) {
|
||||
newContents = newContents.toList();
|
||||
}
|
||||
int removeLength = end - start;
|
||||
|
@ -476,7 +476,7 @@ abstract class ListMixin<E> implements List<E> {
|
|||
|
||||
void insertAll(int index, Iterable<E> iterable) {
|
||||
RangeError.checkValueInInterval(index, 0, length, "index");
|
||||
if (iterable is EfficientLength) {
|
||||
if (iterable is EfficientLengthIterable) {
|
||||
iterable = iterable.toList();
|
||||
}
|
||||
int insertionLength = iterable.length;
|
||||
|
|
|
@ -112,7 +112,7 @@ abstract class UnmodifiableMapBase<K, V> =
|
|||
* map's `operator[]` to lookup the keys.
|
||||
*/
|
||||
class _MapBaseValueIterable<V> extends Iterable<V>
|
||||
implements EfficientLength {
|
||||
implements EfficientLengthIterable<V> {
|
||||
final Map _map;
|
||||
_MapBaseValueIterable(this._map);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ part of dart.collection;
|
|||
* This goes both for using the [iterator] directly, or for iterating an
|
||||
* `Iterable` returned by a method like [map] or [where].
|
||||
*/
|
||||
abstract class Queue<E> implements Iterable<E>, EfficientLength {
|
||||
abstract class Queue<E> implements EfficientLengthIterable<E> {
|
||||
|
||||
/**
|
||||
* Creates a queue.
|
||||
|
@ -482,7 +482,7 @@ class ListQueue<E> extends Iterable<E> implements Queue<E> {
|
|||
return queue;
|
||||
} else {
|
||||
int capacity = _INITIAL_CAPACITY;
|
||||
if (elements is EfficientLength) {
|
||||
if (elements is EfficientLengthIterable) {
|
||||
capacity = elements.length;
|
||||
}
|
||||
ListQueue<E> result = new ListQueue<E>(capacity);
|
||||
|
|
|
@ -600,7 +600,7 @@ abstract class _SplayTreeIterator<T> implements Iterator<T> {
|
|||
}
|
||||
|
||||
class _SplayTreeKeyIterable<K> extends Iterable<K>
|
||||
implements EfficientLength {
|
||||
implements EfficientLengthIterable<K> {
|
||||
_SplayTree<K> _tree;
|
||||
_SplayTreeKeyIterable(this._tree);
|
||||
int get length => _tree._count;
|
||||
|
@ -618,7 +618,7 @@ class _SplayTreeKeyIterable<K> extends Iterable<K>
|
|||
}
|
||||
|
||||
class _SplayTreeValueIterable<K, V> extends Iterable<V>
|
||||
implements EfficientLength {
|
||||
implements EfficientLengthIterable<V> {
|
||||
SplayTreeMap<K, V> _map;
|
||||
_SplayTreeValueIterable(this._map);
|
||||
int get length => _map._count;
|
||||
|
|
|
@ -347,7 +347,7 @@ abstract class Iterable<E> {
|
|||
* Some iterables have a more efficient way to find the number of elements.
|
||||
*/
|
||||
int get length {
|
||||
assert(this is! EfficientLength);
|
||||
assert(this is! EfficientLengthIterable);
|
||||
int count = 0;
|
||||
Iterator it = iterator;
|
||||
while (it.moveNext()) {
|
||||
|
@ -594,7 +594,7 @@ abstract class Iterable<E> {
|
|||
typedef E _Generator<E>(int index);
|
||||
|
||||
class _GeneratorIterable<E> extends Iterable<E>
|
||||
implements EfficientLength {
|
||||
implements EfficientLengthIterable<E> {
|
||||
final int _start;
|
||||
final int _end;
|
||||
final _Generator<E> _generator;
|
||||
|
|
|
@ -51,7 +51,7 @@ part of dart.core;
|
|||
* directly or through iterating an [Iterable] that is backed by the list, will
|
||||
* break the iteration.
|
||||
*/
|
||||
abstract class List<E> implements Iterable<E>, EfficientLength {
|
||||
abstract class List<E> implements EfficientLengthIterable<E> {
|
||||
/**
|
||||
* Creates a list of the given length.
|
||||
*
|
||||
|
|
|
@ -31,7 +31,7 @@ part of dart.core;
|
|||
* iterating either the set itself or any [Iterable] that is backed by the set,
|
||||
* such as the ones returned by methods like [where] and [map].
|
||||
*/
|
||||
abstract class Set<E> extends Iterable<E> implements EfficientLength {
|
||||
abstract class Set<E> implements EfficientLengthIterable<E> {
|
||||
/**
|
||||
* Creates an empty [Set].
|
||||
*
|
||||
|
|
|
@ -4,20 +4,6 @@
|
|||
|
||||
part of dart._internal;
|
||||
|
||||
/**
|
||||
* Marker interface for [Iterable] subclasses that have an efficient
|
||||
* [length] implementation.
|
||||
*/
|
||||
abstract class EfficientLength {
|
||||
/**
|
||||
* Returns the number of elements in the iterable.
|
||||
*
|
||||
* This is an efficient operation that doesn't require iterating through
|
||||
* the elements.
|
||||
*/
|
||||
int get length;
|
||||
}
|
||||
|
||||
/**
|
||||
* An [Iterable] for classes that have efficient [length] and [elementAt].
|
||||
*
|
||||
|
@ -25,7 +11,7 @@ abstract class EfficientLength {
|
|||
* including [iterator].
|
||||
*/
|
||||
abstract class ListIterable<E> extends Iterable<E>
|
||||
implements EfficientLength {
|
||||
implements EfficientLengthIterable<E> {
|
||||
int get length;
|
||||
E elementAt(int i);
|
||||
|
||||
|
@ -351,7 +337,7 @@ class MappedIterable<S, T> extends Iterable<T> {
|
|||
final _Transformation<S, T> _f;
|
||||
|
||||
factory MappedIterable(Iterable iterable, T function(S value)) {
|
||||
if (iterable is EfficientLength) {
|
||||
if (iterable is EfficientLengthIterable) {
|
||||
return new EfficientLengthMappedIterable<S, T>(iterable, function);
|
||||
}
|
||||
return new MappedIterable<S, T>._(iterable, function);
|
||||
|
@ -373,7 +359,7 @@ class MappedIterable<S, T> extends Iterable<T> {
|
|||
}
|
||||
|
||||
class EfficientLengthMappedIterable<S, T> extends MappedIterable<S, T>
|
||||
implements EfficientLength {
|
||||
implements EfficientLengthIterable<T> {
|
||||
EfficientLengthMappedIterable(Iterable iterable, T function(S value))
|
||||
: super._(iterable, function);
|
||||
}
|
||||
|
@ -402,8 +388,7 @@ class MappedIterator<S, T> extends Iterator<T> {
|
|||
*
|
||||
* Expects efficient `length` and `elementAt` on the source iterable.
|
||||
*/
|
||||
class MappedListIterable<S, T> extends ListIterable<T>
|
||||
implements EfficientLength {
|
||||
class MappedListIterable<S, T> extends ListIterable<T> {
|
||||
final Iterable<S> _source;
|
||||
final _Transformation<S, T> _f;
|
||||
|
||||
|
@ -496,7 +481,7 @@ class TakeIterable<E> extends Iterable<E> {
|
|||
if (takeCount is! int || takeCount < 0) {
|
||||
throw new ArgumentError(takeCount);
|
||||
}
|
||||
if (iterable is EfficientLength) {
|
||||
if (iterable is EfficientLengthIterable) {
|
||||
return new EfficientLengthTakeIterable<E>(iterable, takeCount);
|
||||
}
|
||||
return new TakeIterable<E>._(iterable, takeCount);
|
||||
|
@ -510,7 +495,7 @@ class TakeIterable<E> extends Iterable<E> {
|
|||
}
|
||||
|
||||
class EfficientLengthTakeIterable<E> extends TakeIterable<E>
|
||||
implements EfficientLength {
|
||||
implements EfficientLengthIterable<E> {
|
||||
EfficientLengthTakeIterable(Iterable<E> iterable, int takeCount)
|
||||
: super._(iterable, takeCount);
|
||||
|
||||
|
@ -583,7 +568,7 @@ class SkipIterable<E> extends Iterable<E> {
|
|||
final int _skipCount;
|
||||
|
||||
factory SkipIterable(Iterable<E> iterable, int count) {
|
||||
if (iterable is EfficientLength) {
|
||||
if (iterable is EfficientLengthIterable) {
|
||||
return new EfficientLengthSkipIterable<E>(iterable, count);
|
||||
}
|
||||
return new SkipIterable<E>._(iterable, count);
|
||||
|
@ -610,7 +595,7 @@ class SkipIterable<E> extends Iterable<E> {
|
|||
}
|
||||
|
||||
class EfficientLengthSkipIterable<E> extends SkipIterable<E>
|
||||
implements EfficientLength {
|
||||
implements EfficientLengthIterable<E> {
|
||||
EfficientLengthSkipIterable(Iterable<E> iterable, int skipCount)
|
||||
: super._(iterable, skipCount);
|
||||
|
||||
|
@ -672,7 +657,8 @@ class SkipWhileIterator<E> extends Iterator<E> {
|
|||
/**
|
||||
* The always empty [Iterable].
|
||||
*/
|
||||
class EmptyIterable<E> extends Iterable<E> implements EfficientLength {
|
||||
class EmptyIterable<E> extends Iterable<E>
|
||||
implements EfficientLengthIterable<E> {
|
||||
const EmptyIterable();
|
||||
|
||||
Iterator<E> get iterator => const EmptyIterator();
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
// Sanity check on the growing behavior of a growable list.
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
import "dart:collection" show IterableBase;
|
||||
import "dart:collection" show EfficientLengthIterable;
|
||||
|
||||
// Iterable generating numbers in range [0..count).
|
||||
// May perform callback at some point underways.
|
||||
class TestIterableBase extends IterableBase<int> {
|
||||
class TestIterableBase extends Iterable<int> {
|
||||
final int length;
|
||||
final int count;
|
||||
// call [callback] if generating callbackIndex.
|
||||
|
@ -26,9 +26,8 @@ class TestIterable extends TestIterableBase {
|
|||
int get length => throw "SHOULD NOT BE CALLED";
|
||||
}
|
||||
|
||||
// Implement Set for private EfficientLength interface.
|
||||
class EfficientTestIterable extends TestIterableBase
|
||||
implements Set<int> {
|
||||
implements EfficientLengthIterable<int> {
|
||||
EfficientTestIterable(length, count, [callbackIndex = -1, callback])
|
||||
: super(length, count, callbackIndex, callback);
|
||||
// Avoid warnings because we don't actually implement Set.
|
||||
|
@ -57,7 +56,7 @@ class CallbackIterator implements Iterator<int> {
|
|||
|
||||
|
||||
void main() {
|
||||
// Without EfficientLength interface
|
||||
// Without EfficientLengthIterable interface
|
||||
{
|
||||
// Change length of list after 20 additions.
|
||||
var l = [];
|
||||
|
@ -80,7 +79,7 @@ void main() {
|
|||
}, (e) => e is ConcurrentModificationError);
|
||||
}
|
||||
|
||||
// With EfficientLength interface (uses length).
|
||||
// With EfficientLengthIterable interface (uses length).
|
||||
{
|
||||
// Change length of list after 20 additions.
|
||||
var l = [];
|
||||
|
|
Loading…
Reference in a new issue