blob: d2a4ffd52628f842a68995ed7c622f69b84d0bf5 [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/**
* Contains functions that are included by default in [PolymerExpressions].
*
* - [enumerate]: a convenient way to iterate over items and the indexes.
*/
// Code from https://github.com/google/quiver-dart/commit/52edc4baf37e99ff6a8f99c648b29b135fc0b880
library polymer_expressions.src.globals;
import 'dart:collection';
import 'package:observe/observe.dart' show reflectable;
/**
* Returns an [Iterable] of [IndexedValue]s where the nth value holds the nth
* element of [iterable] and its index.
*/
Iterable<IndexedValue> enumerate(Iterable iterable) =>
new EnumerateIterable(iterable);
@reflectable class IndexedValue<V> {
final int index;
final V value;
operator==(o) => o is IndexedValue && o.index == index && o.value == value;
int get hashCode => value.hashCode;
String toString() => '($index, $value)';
IndexedValue(this.index, this.value);
}
/**
* An [Iterable] of [IndexedValue]s where the nth value holds the nth
* element of [iterable] and its index. See [enumerate].
*/
// This was inspired by MappedIterable internal to Dart collections.
class EnumerateIterable<V> extends IterableBase<IndexedValue<V>> {
final Iterable<V> _iterable;
EnumerateIterable(this._iterable);
Iterator<IndexedValue<V>> get iterator =>
new EnumerateIterator<V>(_iterable.iterator);
// Length related functions are independent of the mapping.
int get length => _iterable.length;
bool get isEmpty => _iterable.isEmpty;
// Index based lookup can be done before transforming.
IndexedValue<V> get first => new IndexedValue<V>(0, _iterable.first);
IndexedValue<V> get last => new IndexedValue<V>(length - 1, _iterable.last);
IndexedValue<V> get single => new IndexedValue<V>(0, _iterable.single);
IndexedValue<V> elementAt(int index) =>
new IndexedValue<V>(index, _iterable.elementAt(index));
}
/** The [Iterator] returned by [EnumerateIterable.iterator]. */
class EnumerateIterator<V> extends Iterator<IndexedValue<V>> {
final Iterator<V> _iterator;
int _index = 0;
IndexedValue<V> _current;
EnumerateIterator(this._iterator);
IndexedValue<V> get current => _current;
bool moveNext() {
if (_iterator.moveNext()) {
_current = new IndexedValue(_index++, _iterator.current);
return true;
}
_current = null;
return false;
}
}