import java.util.Collections;
import java.util.Iterator;
+import java.util.NoSuchElementException;
/**
* Iterable that splices other iterables and iterates over them sequentially.
}
+ @Override
public ChainIterable<T> add(@NotNull Iterable<T> another) {
return (ChainIterable<T>)super.add(another);
}
* Convenience: add an item wrapping it into a SingleIterable behind the scenes.
*/
public ChainIterable<T> addItem(@NotNull T item) {
- return (ChainIterable<T>)super.add(Collections.<T>singleton(item));
+ return add(Collections.singleton(item));
}
/**
return (myPayload == null);
}
+ @Override
public Iterator<T> iterator() {
+ return new ChainIterator<T>(this);
+ }
+ @Override
+ public String toString() {
+ return FP.fold(new FP.StringCollector<T>(), this, new StringBuilder()).toString();
+ }
- class IterMixedIn extends ChainIterationMixin<T, Iterable<T>> {
- IterMixedIn(ChainedListBase<Iterable<T>> link) {
- super(link);
- }
-
- @Override
- public Iterator<T> toIterator(Iterable<T> first) {
- return first.iterator();
- }
+ private static class ChainIterator<T> implements Iterator<T> {
+
+ private ChainedListBase<Iterable<T>> myLink; // link of the chain we're currently at
+ private Iterator<T> myCurrent;
+
+ public ChainIterator(@Nullable ChainedListBase<Iterable<T>> initial) {
+ myLink = initial;
}
- final IterMixedIn mixin = new IterMixedIn(this);
-
-
- class Iter extends ChainedListBase<Iterable<T>> implements Iterator<T> {
-
- Iter(ChainedListBase<Iterable<T>> piggybacked) {
- super(piggybacked.myPayload);
- myNext = piggybacked.myNext;
- }
-
- public boolean hasNext() {
- return mixin.hasNext();
+
+ // returns either null or a non-exhausted iterator.
+ @Nullable
+ private Iterator<T> getCurrent() {
+ while ((myCurrent == null || !myCurrent.hasNext()) && (myLink != null && myLink.myPayload != null)) { // fix myCurrent
+ if (myCurrent == null) {
+ myCurrent = myLink.myPayload.iterator();
+ assert myCurrent != null;
+ }
+ else {
+ myLink= myLink.myNext;
+ myCurrent = null;
+ }
}
-
- public void remove() {
- throw new UnsupportedOperationException(); // we don't remove things
+ return myCurrent;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return getCurrent() != null;
+ }
+
+ @Override
+ public T next() {
+ final Iterator<T> current = getCurrent();
+ if (current != null) {
+ return current.next();
}
-
- public T next() {
- //noinspection RedundantCast
- return (T)mixin.next();
+ else {
+ throw new NoSuchElementException();
}
-
}
-
- return new Iter(this);
-
- }
-
- @Override
- public String toString() {
- return FP.fold(new FP.StringCollector<T>(), this, new StringBuilder()).toString();
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Cannot remove from ChainIterator");
+ }
}
}
+++ /dev/null
-/*
- * Copyright 2000-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 com.jetbrains.python.toolbox;
-
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * Common logic of chain iterators.
- * User: dcheryasov
- * Date: Nov 20, 2009 9:10:39 AM
- */
-/* explicitly not public */
-abstract class ChainIterationMixin<T, TPayload> {
- protected ChainedListBase<TPayload> myLink; // link of the chain we're currently at
-
- protected Iterator<T> myCurrent;
-
- public ChainIterationMixin(ChainedListBase<TPayload> link) {
- myLink = link;
- }
-
- abstract public Iterator<T> toIterator(TPayload first);
-
- // returns either null or a non-exhausted iterator.
- @Nullable
- public Iterator<T> getCurrent() {
- while ((myCurrent == null || !myCurrent.hasNext()) && (myLink != null && myLink.myPayload != null)) { // fix myCurrent
- if (myCurrent == null) {
- myCurrent = toIterator(myLink.myPayload);
- assert myCurrent != null;
- }
- else {
- myLink= myLink.myNext;
- myCurrent = null;
- }
- }
- return myCurrent;
- }
-
- public boolean hasNext() {
- return getCurrent() != null;
- }
-
- public T next() {
- Iterator<T> current = getCurrent();
- if (current != null) return current.next();
- else throw new NoSuchElementException();
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2000-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 com.jetbrains.python.toolbox;
-
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Iterator;
-
-/**
- * An iterator that combines several other iterators and exhaust them one by one, in chain.
- * User: dcheryasov
- * Date: Nov 19, 2009 3:49:38 AM
- */
-public class ChainIterator<T> extends ChainedListBase<Iterator<T>> implements Iterator<T> {
-
- private ChainIterationMixin<T, Iterator<T>> myMixin;
-
- /**
- * Creates new instance.
- * @param initial initial iterator. If null, the new iterator is empty, use {@link #add} to add initial content.
- */
- public ChainIterator(@Nullable Iterator<T> initial) {
- super(initial);
-
- myMixin = new ChainIterationMixin<T, Iterator<T>>(this) {
- @Override
- public Iterator<T> toIterator(Iterator<T> first) {
- return first;
- }
- };
- }
-
-
- /**
- * Adds another iterator to the chain. Values from this iterator will follow the values of the iterator passed to the constructor.
- * Adding after the iteration has started is safe.
- * @param another iterator to add to the end of the chain.
- * @return self, for easy chaining.
- */
- public ChainIterator<T> add(Iterator<T> another) {
- return (ChainIterator<T>)super.add(another);
- }
-
-
- public boolean hasNext() {
- return myMixin.hasNext();
- }
-
- public T next() {
- return myMixin.next();
- }
-
- public void remove() {
- throw new UnsupportedOperationException("Cannot remove from ChainIterator");
- }
-}
myPayload = initial;
}
- /**
- * Wrap payload into a new linked list element.
- * @param payload
- * @return
- */
- /*
- abstract protected ChainedListBase<TPayload> createInstance(TPayload payload);
- */
-
/**
* Add another element to the end of our linked list
* @param another
+++ /dev/null
-/*
- * Copyright 2000-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 com.jetbrains.python.toolbox;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Iterable that endlessly repeat the same sequence.
- * User: dcheryasov
- * Date: Nov 8, 2009 6:32:08 AM
- */
-public class RepeatIterable<T> implements Iterable<T> {
- private final List<T> master;
-
- /**
- * Create an iterator that repeats the contents of given list.
- * @param master the list to repeat
- */
- public RepeatIterable(@NotNull List<T> master) {
- this.master = master;
- }
-
- /**
- * Create an iterator that repeats given value.
- * @param single the value to repeat
- */
- public RepeatIterable(@NotNull T single) {
- master = new ArrayList<T>(1);
- master.add(single);
- }
-
- public Iterator<T> iterator() {
- return new RepeatIterator<T>(master);
- }
-}
+++ /dev/null
-/*
- * Copyright 2000-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 com.jetbrains.python.toolbox;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-/**
- * An iterator that endlessly repeats the same contents.
- * User: dcheryasov
- * Date: Nov 8, 2009 5:55:57 AM
- */
-public class RepeatIterator<T> implements Iterator<T> {
- private final List<T> master;
- private Iterator<T> source;
-
- /**
- * Create an iterator that repeats the contents of given list.
- * @param master the list to repeat
- */
- public RepeatIterator(@NotNull List<T> master) {
- this.master = master;
- this.source = master.iterator();
- }
-
- /**
- * Create an iterator that repeats given value.
- * @param single the value to repeat
- */
- public RepeatIterator(@NotNull T single) {
- master = new ArrayList<T>(1);
- master.add(single);
- source = master.iterator();
- }
-
- public boolean hasNext() {
- return master.size() > 0;
- }
-
- public void remove() {
- throw new UnsupportedOperationException("This is a read-only endless iterator");
- }
-
- public T next() {
- if (! hasNext()) throw new NoSuchElementException();
- if (!source.hasNext()) source = master.iterator();
- return source.next();
- }
-}
super();
}
- public void testRepeatIterable() {
- String value = "foo";
- RepeatIterable<String> tested = new RepeatIterable<String>(value);
- int count = 0;
- int times = 10;
- for (String what : tested) {
- assertEquals(value, what);
- count += 1;
- if (count >= times) break;
- }
- assertEquals(times, count);
- }
-
public void testChainIterableByLists() {
List<String> list1 = Arrays.asList("foo", "bar", "baz");
List<String> list2 = Arrays.asList("ichi", "ni", "san");
assertEquals(all.size(), count);
}
-
- public void testChainIteratorByLists() {
- List<String> list1 = Arrays.asList("foo", "bar", "baz");
- List<String> list2 = Arrays.asList("ichi", "ni", "san");
- List<String> list3 = Arrays.asList("a", "s", "d", "f");
- List<String> all = new ArrayList<String>();
- all.addAll(list1);
- all.addAll(list2);
- all.addAll(list3);
- ChainIterator<String> tested = new ChainIterator<String>(list1.iterator()).add(list2.iterator()).add(list3.iterator());
- int count = 0;
- String what;
- while (tested.hasNext()) {
- what = tested.next();
- assertEquals(all.get(count), what);
- count += 1;
- }
- assertEquals(all.size(), count);
- }
-
- public void testChainIteratorEmptyFirst() {
- List<String> list1 = Arrays.asList();
- List<String> list2 = Arrays.asList("ichi", "ni", "san");
- List<String> list3 = Arrays.asList("a", "s", "d", "f");
- List<String> all = new ArrayList<String>();
- all.addAll(list1);
- all.addAll(list2);
- all.addAll(list3);
- ChainIterator<String> tested = new ChainIterator<String>(list1.iterator()).add(list2.iterator()).add(list3.iterator());
- int count = 0;
- String what;
- while (tested.hasNext()) {
- what = tested.next();
- assertEquals(all.get(count), what);
- count += 1;
- }
- assertEquals(all.size(), count);
- }
-
- public void testChainIteratorEmptyLast() {
- List<String> list1 = Arrays.asList("foo", "bar", "baz");
- List<String> list2 = Arrays.asList("ichi", "ni", "san");
- List<String> list3 = Arrays.asList();
- List<String> all = new ArrayList<String>();
- all.addAll(list1);
- all.addAll(list2);
- all.addAll(list3);
- ChainIterator<String> tested = new ChainIterator<String>(list1.iterator()).add(list2.iterator()).add(list3.iterator());
- int count = 0;
- String what;
- while (tested.hasNext()) {
- what = tested.next();
- assertEquals(all.get(count), what);
- count += 1;
- }
- assertEquals(all.size(), count);
- }
-
- public void testChainIteratorEmptyMiddle() {
- List<String> list1 = Arrays.asList("foo", "bar", "baz");
- List<String> list2 = Arrays.asList();
- List<String> list3 = Arrays.asList("a", "s", "d", "f");
- List<String> all = new ArrayList<String>();
- all.addAll(list1);
- all.addAll(list2);
- all.addAll(list3);
- ChainIterator<String> tested = new ChainIterator<String>(list1.iterator()).add(list2.iterator()).add(list3.iterator());
- int count = 0;
- String what;
- while (tested.hasNext()) {
- what = tested.next();
- assertEquals(all.get(count), what);
- count += 1;
- }
- assertEquals(all.size(), count);
- }
-
public void testToStringDoesntExhaustIterator() {
final ChainIterable<String> initial = new ChainIterable<String>();
initial.addItem("foo");