001/**
002 * @author Francesco.Kriegel@gmx.de
003 */
004package conexp.fx.core.collections.setlist;
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.Arrays;
029import java.util.Collection;
030import java.util.ListIterator;
031
032import com.google.common.base.Function;
033import com.google.common.base.Predicate;
034import com.google.common.base.Predicates;
035
036import conexp.fx.core.collections.ListIterators;
037import conexp.fx.core.collections.Pair;
038
039public final class SetLists {
040
041  public static final <E> SetList<E> empty() {
042    return new UnmodifiableSetList<E>() {
043
044      public final ListIterator<E> listIterator(final int i) {
045        return ListIterators.<E> empty();
046      }
047    };
048  }
049
050  public static final <E> HashSetArrayList<E> create(@SuppressWarnings("unchecked") final E... e) {
051    return create(Arrays.asList(e));
052  }
053
054  public static final <E> HashSetArrayList<E> create(final Collection<? extends E> c) {
055    return new HashSetArrayList<E>(c);
056  }
057
058  public static final <E> SetList<E> unmodifiable(final SetList<E> s) {
059    if (s instanceof UnmodifiableSetList)
060      return (UnmodifiableSetList<E>) s;
061    return new UnmodifiableSetList<E>() {
062
063      public final ListIterator<E> listIterator(final int i) {
064        return ListIterators.unmodifiable(s.listIterator(i));
065      }
066    };
067  }
068
069  public static final <E> SetList<E> filter(final SetList<? extends E> s, final Predicate<? super E> p) {
070    return new UnmodifiableSetList<E>() {
071
072      public final ListIterator<E> listIterator(final int i) {
073        return ListIterators.filter(s.listIterator(), p, i);
074      }
075    };
076  }
077
078  public static final <T, E> SetList<E> transform(final SetList<? extends T> s, final Function<? super T, E> f) {
079    return new UnmodifiableSetList<E>() {
080
081      public final ListIterator<E> listIterator(final int i) {
082        return ListIterators.transform(s.listIterator(i), f);
083      }
084    };
085  }
086
087  public static final SetList<Integer> integers(final int size) {
088    return new UnmodifiableSetList<Integer>() {
089
090      public final ListIterator<Integer> listIterator(final int i) {
091        return ListIterators.integers(i, size);
092      }
093
094      @Override
095      public final int size() {
096        return size;
097      }
098    };
099  }
100
101  public static final <T, E> SetList<Pair<T, E>> disjointUnion(final SetList<T> s1, final SetList<E> s2) {
102    return new UnmodifiableSetList<Pair<T, E>>() {
103
104      public final ListIterator<Pair<T, E>> listIterator(final int i) {
105        return ListIterators.disjointUnion(s1.listIterator(), s2.listIterator(), i);
106      }
107    };
108  }
109
110  public static final <T, E> SetList<Pair<T, E>> cartesianProduct(final SetList<T> s1, final SetList<E> s2) {
111    return new UnmodifiableSetList<Pair<T, E>>() {
112
113      public final ListIterator<Pair<T, E>> listIterator(final int i) {
114        return ListIterators.cartesianProduct(s1.listIterator(), s2.listIterator(), i);
115      }
116    };
117  }
118
119  public static final <E> SetList<E> union(final SetList<? extends E> s1, final SetList<? extends E> s2) {
120    return new UnmodifiableSetList<E>() {
121
122      public final ListIterator<E> listIterator(final int i) {
123        return ListIterators
124            .concat(s1.listIterator(), ListIterators.filter(s2.listIterator(), Predicates.not(Predicates.in(s1))), i);
125      }
126    };
127  }
128
129  public static final <E> SetList<E> intersection(final SetList<E> s, final Collection<?> c) {
130    return new UnmodifiableSetList<E>() {
131
132      public final ListIterator<E> listIterator(final int i) {
133        return ListIterators.filter(s.listIterator(), Predicates.in(c), i);
134      }
135    };
136  }
137
138  public static final <E> SetList<E> difference(final SetList<E> s, final Collection<?> c) {
139    return new UnmodifiableSetList<E>() {
140
141      public final ListIterator<E> listIterator(final int i) {
142        return ListIterators.filter(s.listIterator(), Predicates.not(Predicates.in(c)), i);
143      }
144    };
145  }
146
147  public static final <E> SetList<SetList<E>> powerSet(final SetList<E> s) {
148    return new UnmodifiableSetList<SetList<E>>() {
149
150      private final int size = 1 << s.size();
151
152      public final int size() {
153        return size;
154      }
155
156      public final boolean isEmpty() {
157        return false;
158      }
159
160      public final SetList<E> get(final int i) {
161        if (i < 0 || i > size)
162          throw new IndexOutOfBoundsException();
163        return new UnmodifiableSetList<E>() {
164
165          public ListIterator<E> listIterator(final int j) {
166            return ListIterators.filter(s.listIterator(), new Predicate<E>() {
167
168              public final boolean apply(final E e) {
169                return (i >> s.indexOf(e)) % 2 == 1;
170              }
171            }, j);
172          }
173        };
174      }
175
176      public final ListIterator<SetList<E>> listIterator(final int i) {
177        return ListIterators.transform(ListIterators.integers(i, size), new Function<Integer, SetList<E>>() {
178
179          public final SetList<E> apply(final Integer j) {
180            return get(j);
181          }
182        });
183      }
184    };
185  }
186}