blob: 92c7c7919369cd6a7c8180d9d11d1ab3d72dba1b [file] [log] [blame]
// Copyright (c) 2016, 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.
/// @assertion When iteration over the iterable is started, by getting an
/// iterator j from the iterable and calling moveNext(), execution of the body
/// of f will begin. When f terminates, j is positioned after its last element,
/// so that its current value is null and the current call to moveNext() on j
/// returns false, as will all further calls.
/// Each iterator starts a separate computation. If the sync* function is
/// impure, the sequence of values yielded by each iterator may differ.
/// One can derive more than one iterator from a given iterable. Note that
/// operations on the iterable itself can create distinct iterators. An example
/// would be length. It is conceivable that different iterators might yield
/// sequences of different length. The same care needs to be taken when writing
/// sync* functions as when writing an Iterator class. In particular, it should
/// handle multiple simultaneous iterators gracefully. If the iterator depends
/// on external state that might change, it should check that the state is still
/// valid after every yield (and maybe throw a ConcurrentModificationError if
/// it isn’t).
/// Each iterator runs with its own shallow copies of all local variables; in
/// particular, each iterator has the same initial arguments, even if their
/// bindings are modified by the function. Two executions of an iterator
/// interact only via state outside the function.
///
/// @description Check that each iterator runs with its own shallow copies of
/// all local variables.
///
/// @author a.semenov@unipro.ru
import '../../../Utils/expect.dart';
const int COUNT = 100;
Iterable generator() sync* {
int i = 0;
while ( i < COUNT ) {
yield i++;
}
}
// first iterator is running two times faster than second
test1() {
Iterable iterable = generator();
Iterator iterator1 = iterable.iterator;
Iterator iterator2 = iterable.iterator;
int k = 0;
int i = 0;
while ( i < COUNT/2 ) {
Expect.isTrue(iterator1.moveNext());
Expect.equals(k++, iterator1.current);
Expect.isTrue(iterator2.moveNext());
Expect.equals(i++, iterator2.current);
Expect.isTrue(iterator1.moveNext());
Expect.equals(k++, iterator1.current);
}
Expect.isFalse(iterator1.moveNext());
Expect.isNull(iterator1.current);
while ( i < COUNT ) {
Expect.isTrue(iterator2.moveNext());
Expect.equals(i++, iterator2.current);
}
Expect.isFalse(iterator1.moveNext());
Expect.isNull(iterator1.current);
Expect.isFalse(iterator2.moveNext());
Expect.isNull(iterator2.current);
}
// five iterators, each has its own speed
test2() {
Iterable iterable = generator();
List<Iterator> iterator = [
iterable.iterator,
iterable.iterator,
iterable.iterator,
iterable.iterator,
iterable.iterator
];
List<int> expected = [ 0, 0, 0, 0, 0 ];
List<int> speed = [ 1, 2, 3, 4, 5 ];
for (int n = 0; n < COUNT; n++) {
for (int i = 0; i < iterator.length; i++) {
Iterator it = iterator[i];
for (int k = 0; expected[i] < COUNT && k < speed[i]; k++) {
Expect.isTrue(it.moveNext());
Expect.equals(expected[i]++, it.current);
}
}
}
for (int i = 0; i < iterator.length; i++) {
Expect.isFalse(iterator[i].moveNext());
Expect.isNull(iterator[i].current);
}
}
main() {
test1();
test2();
}