001/**
002 * @author Francesco.Kriegel@gmx.de
003 */
004package conexp.fx.core.collections;
005
006/*
007 * #%L
008 * Concept Explorer FX
009 * %%
010 * Copyright (C) 2010 - 2019 Francesco Kriegel
011 * %%
012 * This program is free software: you can redistribute it and/or modify
013 * it under the terms of the GNU General Public License as
014 * published by the Free Software Foundation, either version 3 of the
015 * License, or (at your option) any later version.
016 * 
017 * This program is distributed in the hope that it will be useful,
018 * but WITHOUT ANY WARRANTY; without even the implied warranty of
019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
020 * GNU General Public License for more details.
021 * 
022 * You should have received a copy of the GNU General Public
023 * License along with this program.  If not, see
024 * <http://www.gnu.org/licenses/gpl-3.0.html>.
025 * #L%
026 */
027
028import java.util.Iterator;
029import java.util.ListIterator;
030import java.util.NoSuchElementException;
031
032import com.google.common.base.Function;
033import com.google.common.base.Predicate;
034import com.google.common.collect.UnmodifiableIterator;
035import com.google.common.collect.UnmodifiableListIterator;
036
037public final class ListIterators {
038
039  public static final <E> ListIterator<E> empty() {
040    return new UnmodifiableListIterator<E>() {
041
042      public final boolean hasNext() {
043        return false;
044      }
045
046      public final E next() {
047        return null;
048      }
049
050      public final boolean hasPrevious() {
051        return false;
052      }
053
054      public final E previous() {
055        return null;
056      }
057
058      public final int nextIndex() {
059        return 0;
060      }
061
062      public final int previousIndex() {
063        return -1;
064      }
065    };
066  }
067
068  public static final ListIterator<Integer> integers(final int size) {
069    return integers(0, size);
070  }
071
072  public static final ListIterator<Integer> integers(final int i, final int size) {
073    return new UnmodifiableListIterator<Integer>() {
074
075      private int j = i - 1;
076
077      public synchronized final boolean hasNext() {
078        return j < size - 1;
079      }
080
081      public synchronized final Integer next() {
082        if (!hasNext())
083          throw new NoSuchElementException();
084        return ++j;
085      }
086
087      public final boolean hasPrevious() {
088        return j > -1;
089      }
090
091      public final Integer previous() {
092        if (!hasPrevious())
093          throw new NoSuchElementException();
094        return j--;
095      }
096
097      public synchronized final int nextIndex() {
098        return j + 1;
099      }
100
101      public final int previousIndex() {
102        return j;
103      }
104    };
105  }
106
107  public static final <E> UnmodifiableListIterator<E> unmodifiable(final ListIterator<E> it) {
108    if (it instanceof UnmodifiableListIterator)
109      return (UnmodifiableListIterator<E>) it;
110    return new UnmodifiableListIterator<E>() {
111
112      public final boolean hasNext() {
113        return it.hasNext();
114      }
115
116      public final E next() {
117        return it.next();
118      }
119
120      public final boolean hasPrevious() {
121        return it.hasPrevious();
122      }
123
124      public final E previous() {
125        return it.previous();
126      }
127
128      public final int nextIndex() {
129        return it.nextIndex();
130      }
131
132      public final int previousIndex() {
133        return it.previousIndex();
134      }
135    };
136  }
137
138  public static final <T, E> ListIterator<E>
139      transform(final ListIterator<? extends T> it, final Function<? super T, E> f) {
140    return new UnmodifiableListIterator<E>() {
141
142      public final boolean hasNext() {
143        return it.hasNext();
144      }
145
146      public final E next() {
147        return f.apply(it.next());
148      }
149
150      public final boolean hasPrevious() {
151        return it.hasPrevious();
152      }
153
154      public final E previous() {
155        return f.apply(it.previous());
156      }
157
158      public final int nextIndex() {
159        return it.nextIndex();
160      }
161
162      public final int previousIndex() {
163        return it.previousIndex();
164      }
165    };
166  }
167
168  public static final <E> ListIterator<E> filter(final ListIterator<? extends E> it, final Predicate<? super E> p) {
169    return filter(it, p, 0);
170  }
171
172  public static final <E> ListIterator<E>
173      filter(final ListIterator<? extends E> it, final Predicate<? super E> p, final int i) {
174    return new SimpleListIterator<E>(i) {
175
176      protected final E createNext() {
177        while (it.hasNext()) {
178          final E next = it.next();
179          if (p.apply(next))
180            return next;
181        }
182        return null;
183      }
184
185      protected final E createPrevious() {
186        while (it.hasPrevious()) {
187          final E prev = it.previous();
188          if (p.apply(prev))
189            return prev;
190        }
191        return null;
192      }
193    };
194  }
195
196  public static final <E> ListIterator<E>
197      concat(final ListIterator<? extends E> it1, final ListIterator<? extends E> it2, final int i) {
198    return new SimpleListIterator<E>(i) {
199
200      protected final E createNext() {
201        if (it1.hasNext())
202          return it1.next();
203        if (it2.hasNext())
204          return it2.next();
205        return null;
206      }
207
208      protected final E createPrevious() {
209        if (it2.hasPrevious())
210          return it2.previous();
211        if (it1.hasPrevious())
212          return it1.previous();
213        return null;
214      }
215    };
216  }
217
218  public static final <T, E> ListIterator<Pair<T, E>>
219      disjointUnion(final ListIterator<T> it1, final ListIterator<E> it2, final int i) {
220    return new SimpleListIterator<Pair<T, E>>(i) {
221
222      protected final Pair<T, E> createNext() {
223        if (it1.hasNext())
224          return new Pair<T, E>(it1.next(), null);
225        if (it2.hasNext())
226          return new Pair<T, E>(null, it2.next());
227        return null;
228      }
229
230      protected final Pair<T, E> createPrevious() {
231        if (it2.hasPrevious())
232          return new Pair<T, E>(null, it2.previous());
233        if (it1.hasPrevious())
234          return new Pair<T, E>(it1.previous(), null);
235        return null;
236      }
237    };
238  }
239
240  public static final <T, E> ListIterator<Pair<T, E>>
241      cartesianProduct(final ListIterator<T> it1, final ListIterator<E> it2, final int i) {
242    return new SimpleListIterator<Pair<T, E>>(true) {
243
244      private T t = it1.hasNext() ? it1.next() : null;
245      {
246        createFirst(i);
247      }
248
249      protected final Pair<T, E> createNext() {
250        if (t != null && it2.hasNext())
251          return new Pair<T, E>(t, it2.next());
252        else if (it1.hasNext()) {
253          t = it1.next();
254          while (it2.hasPrevious())
255            it2.previous();
256          if (it2.hasNext())
257            return new Pair<T, E>(t, it2.next());
258        }
259        return null;
260      }
261
262      protected final Pair<T, E> createPrevious() {
263        if (t != null && it2.hasPrevious())
264          return new Pair<T, E>(t, it2.previous());
265        else if (it1.hasPrevious()) {
266          t = it1.previous();
267          while (it2.hasNext())
268            it2.next();
269          if (it2.hasPrevious())
270            return new Pair<T, E>(t, it2.previous());
271        }
272        return null;
273      }
274    };
275  }
276
277  public static final <E> Iterable<Pair<E, E>> upperCartesianDiagonal(final Iterable<E> it) {
278    return new Iterable<Pair<E, E>>() {
279
280      @Override
281      public final Iterator<Pair<E, E>> iterator() {
282        if (!it.iterator().hasNext())
283          return empty();
284//          return Iterators.emptyIterator();
285        return new UnmodifiableIterator<Pair<E, E>>() {
286
287          private final Iterator<E> it1   = it.iterator();
288          private Iterator<E>       it2   = it.iterator();
289          private E                 e1    = it1.next();
290          private int               skip2 = 0;
291
292          @Override
293          public final boolean hasNext() {
294            return e1 != null;
295          }
296
297          @Override
298          public final Pair<E, E> next() {
299            if (!it2.hasNext()) {
300              e1 = it1.next();
301              it2 = it.iterator();
302              ++skip2;
303              for (int i = 0; i < skip2; i++)
304                it2.next();
305            }
306            final Pair<E, E> p = Pair.of(e1, it2.next());
307            if (!it2.hasNext() && !it1.hasNext())
308              e1 = null;
309            return p;
310          }
311        };
312      }
313    };
314  }
315
316  public static final <E> Iterable<Pair<E, E>> upperCartesianDiagonalStrict(final Iterable<E> it) {
317    return new Iterable<Pair<E, E>>() {
318
319      @Override
320      public final Iterator<Pair<E, E>> iterator() {
321        Iterator<E> _it = it.iterator();
322        if (!_it.hasNext())
323          return empty();
324//          return Iterators.emptyIterator();
325        _it.next();
326        if (!_it.hasNext())
327          return empty();
328//          return Iterators.emptyIterator();
329        return new UnmodifiableIterator<Pair<E, E>>() {
330
331          private final Iterator<E> it1   = it.iterator();
332          private Iterator<E>       it2   = it.iterator();
333          private E                 e1    = it1.next();
334          private int               skip2 = 1;
335          {
336            it2.next();
337          }
338
339          @Override
340          public final boolean hasNext() {
341            return e1 != null;
342          }
343
344          @Override
345          public final Pair<E, E> next() {
346            final Pair<E, E> p = Pair.of(e1, it2.next());
347            if (!it2.hasNext()) {
348              if (it1.hasNext()) {
349                e1 = it1.next();
350                if (!it1.hasNext())
351                  e1 = null;
352                else {
353                  it2 = it.iterator();
354                  ++skip2;
355                  for (int i = 0; i < skip2; i++)
356                    it2.next();
357                }
358              } else {
359                e1 = null;
360              }
361            }
362            return p;
363          }
364        };
365      }
366    };
367  }
368}