2 * Copyright 2000-2014 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.jetbrains.python.toolbox;
18 import org.jetbrains.annotations.NotNull;
19 import org.jetbrains.annotations.Nullable;
21 import java.util.Collections;
22 import java.util.Iterator;
25 * Iterable that splices other iterables and iterates over them sequentially.
27 * Date: Nov 20, 2009 8:01:23 AM
29 public class ChainIterable<T> extends ChainedListBase<Iterable<T>> implements Iterable<T> {
31 public ChainIterable(@Nullable Iterable<T> initial) {
35 public ChainIterable() {
39 public ChainIterable(@NotNull T initial) {
40 super(Collections.singleton(initial));
44 public ChainIterable<T> add(@NotNull Iterable<T> another) {
45 return (ChainIterable<T>)super.add(another);
49 * Apply wrapper to another and add the result. Convenience to avoid cluttering code with apply() calls.
54 public ChainIterable<T> addWith(FP.Lambda1<Iterable<T>, Iterable<T>> wrapper, Iterable<T> another) {
55 return (ChainIterable<T>)super.add(wrapper.apply(another));
59 * Convenience: add an item wrapping it into a SingleIterable behind the scenes.
61 public ChainIterable<T> addItem(@NotNull T item) {
62 return (ChainIterable<T>)super.add(Collections.<T>singleton(item));
66 * Convenience, works without ever touching an iterator.
67 * @return true if the chain contains at least one iterable (but all iterables in the chain may happen to be empty).
69 public boolean isEmpty() {
70 return (myPayload == null);
73 public Iterator<T> iterator() {
76 class IterMixedIn extends ChainIterationMixin<T, Iterable<T>> {
77 IterMixedIn(ChainedListBase<Iterable<T>> link) {
82 public Iterator<T> toIterator(Iterable<T> first) {
83 return first.iterator();
86 final IterMixedIn mixin = new IterMixedIn(this);
89 class Iter extends ChainedListBase<Iterable<T>> implements Iterator<T> {
91 Iter(ChainedListBase<Iterable<T>> piggybacked) {
92 super(piggybacked.myPayload);
93 myNext = piggybacked.myNext;
96 public boolean hasNext() {
97 return mixin.hasNext();
100 public void remove() {
101 throw new UnsupportedOperationException(); // we don't remove things
105 //noinspection RedundantCast
106 return (T)mixin.next();
111 return new Iter(this);
116 public String toString() {
117 return FP.fold(new FP.StringCollector<T>(), this, new StringBuilder()).toString();