/*
* Copyright 2003-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jetbrains.mps.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* Evgeny Gryaznov, Feb 10, 2010
* <p/>
* Iterates over superposition of Iterables.
*/
public class FlattenIterable<T> implements Iterable<T> {
private Collection<Iterable<T>> myContent;
public FlattenIterable() {
myContent = new ArrayList<Iterable<T>>();
}
public FlattenIterable(int initialCapacity) {
myContent = new ArrayList<Iterable<T>>(initialCapacity);
}
public FlattenIterable(Collection<? extends Iterable<T>> content) {
myContent = new ArrayList<Iterable<T>>(content);
}
public void add(Iterable<T> e) {
myContent.add(e);
}
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
Iterator<Iterable<T>> currentOuter;
Iterator<T> currentInner;
T next;
{
currentOuter = myContent.iterator();
next = nextInternal();
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public T next() {
T curr = next;
next = nextInternal();
return curr;
}
private T nextInternal() {
if (currentInner != null && currentInner.hasNext()) {
return currentInner.next();
}
while (currentOuter.hasNext()) {
Iterable<T> innerIterable = currentOuter.next();
currentInner = innerIterable != null ? innerIterable.iterator() : null;
if (currentInner != null && currentInner.hasNext()) {
return currentInner.next();
}
}
return null;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}