(this, silent);
+ }
+
+ /**
+ * Repeatedly calls the given callable indefinitely and
+ * emits the returned value.
+ *
+ * The result's iterator() doesn't support remove().
+ * @param the value type
+ * @param callable the callable to call
+ * @return the new Ix instance
+ * @since 1.0
+ */
+ public static Ix repeatCallable(Callable callable) {
+ return new IxRepeatCallable(nullCheck(callable, "callable is null"));
+ }
+
/**
* Repeats the given value indefinitely.
*
@@ -738,6 +827,52 @@ public final Ix> buffer(int size, int skip) {
return new IxBufferOverlap(this, positive(size, "size"), positive(skip, "skip"));
}
+ /**
+ * Buffer until an item is encountered for which the predicate returns true,
+ * triggering a new buffer.
+ * Neither the previous nor the next buffer will contain the item that caused the
+ * split
+ * @param predicate the predicate called with each item and should return false
+ * to trigger a new buffer
+ * @return the new Ix instance
+ * @see #bufferUntil(IxPredicate)
+ * @see #bufferWhile(IxPredicate)
+ * @since 1.0
+ */
+ public final Ix> bufferSplit(IxPredicate super T> predicate) {
+ return new IxBufferSplit(this, nullCheck(predicate, "predicate is null"));
+ }
+
+ /**
+ * Buffer until an item is encountered after which the predicate returns true
+ * to start a new buffer.
+ * The item will be part of the previous buffer.
+ * @param predicate the predicate called with each item after the item
+ * has been added to the current buffer and should return true to start a new buffer
+ * @return the new Ix instance
+ * @see #bufferSplit(IxPredicate)
+ * @see #bufferWhile(IxPredicate)
+ * @since 1.0
+ */
+ public final Ix> bufferUntil(IxPredicate super T> predicate) {
+ return new IxBufferUntil(this, nullCheck(predicate, "predicate is null"));
+ }
+
+ /**
+ * Buffer while an item is encountered before which the predicate returns false
+ * to start a new buffer.
+ * The item will be part of the next buffer
+ * @param predicate the predicate called with each item after the item
+ * has been added to the current buffer and should return true to start a new buffer
+ * @return the new Ix instance
+ * @see #bufferSplit(IxPredicate)
+ * @see #bufferUntil(IxPredicate)
+ * @since 1.0
+ */
+ public final Ix> bufferWhile(IxPredicate super T> predicate) {
+ return new IxBufferWhile(this, nullCheck(predicate, "predicate is null"));
+ }
+
/**
* Cast the elements to the specified class.
*
@@ -1095,6 +1230,17 @@ public final Ix endWith(T... values) {
return concat(this, fromArray(values));
}
+ /**
+ * Emit every Nth item only from upstream.
+ * Example: Ix.range(1, 5).every(2) will yield {2, 4}.
+ * @param nth how many items to skip + 1
+ * @return the new Ix instance
+ * @since 1.0
+ */
+ public final Ix every(int nth) {
+ return new IxEvery(this, positive(nth, "nth"));
+ }
+
/**
* Emits distinct elements from this and the other Iterable which are not
* in the other sequence (i.e., (A union B) minus (A intersection B)).
diff --git a/src/main/java/ix/IxBufferSplit.java b/src/main/java/ix/IxBufferSplit.java
new file mode 100644
index 0000000..e354496
--- /dev/null
+++ b/src/main/java/ix/IxBufferSplit.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2011-2016 David Karnok
+ *
+ * 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 ix;
+
+import java.util.*;
+
+/**
+ * Split into buffers when the predicate returns true and neither
+ * buffer contains the item.
+ *
+ * @param the value type
+ */
+final class IxBufferSplit extends IxSource> {
+
+ final IxPredicate super T> predicate;
+
+ IxBufferSplit(Iterable source, IxPredicate super T> predicate) {
+ super(source);
+ this.predicate = predicate;
+ }
+
+ @Override
+ public Iterator> iterator() {
+ return new BufferSplitIterator(source.iterator(), predicate);
+ }
+
+ static final class BufferSplitIterator implements Iterator> {
+
+ final Iterator source;
+
+ final IxPredicate super T> predicate;
+
+ boolean done;
+
+ List buffer;
+
+ BufferSplitIterator(Iterator source, IxPredicate super T> predicate) {
+ this.source = source;
+ this.predicate = predicate;
+ }
+
+ @Override
+ public boolean hasNext() {
+ List b = buffer;
+ if (b == null) {
+ if (done) {
+ return false;
+ }
+
+ b = new ArrayList();
+
+ Iterator src = source;
+ while (src.hasNext()) {
+ T v = src.next();
+
+ if (predicate.test(v)) {
+ buffer = b;
+ return true;
+ }
+
+ b.add(v);
+ }
+
+ if (b.isEmpty()) {
+ done = true;
+ return false;
+ }
+
+ buffer = b;
+ }
+ return true;
+ }
+
+ @Override
+ public List next() {
+ if (hasNext()) {
+ List b = buffer;
+ buffer = null;
+ return b;
+ }
+ throw new NoSuchElementException();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/src/main/java/ix/IxBufferUntil.java b/src/main/java/ix/IxBufferUntil.java
new file mode 100644
index 0000000..6a1e72c
--- /dev/null
+++ b/src/main/java/ix/IxBufferUntil.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2011-2016 David Karnok
+ *
+ * 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 ix;
+
+import java.util.*;
+
+/**
+ * Split into buffers when the predicate returns true and neither
+ * buffer contains the item.
+ *
+ * @param the value type
+ */
+final class IxBufferUntil extends IxSource> {
+
+ final IxPredicate super T> predicate;
+
+ IxBufferUntil(Iterable source, IxPredicate super T> predicate) {
+ super(source);
+ this.predicate = predicate;
+ }
+
+ @Override
+ public Iterator> iterator() {
+ return new BufferSplitIterator(source.iterator(), predicate);
+ }
+
+ static final class BufferSplitIterator implements Iterator> {
+
+ final Iterator source;
+
+ final IxPredicate super T> predicate;
+
+ boolean done;
+
+ List buffer;
+
+ BufferSplitIterator(Iterator source, IxPredicate super T> predicate) {
+ this.source = source;
+ this.predicate = predicate;
+ }
+
+ @Override
+ public boolean hasNext() {
+ List b = buffer;
+ if (b == null) {
+ if (done) {
+ return false;
+ }
+
+ b = new ArrayList();
+
+ Iterator src = source;
+ while (src.hasNext()) {
+ T v = src.next();
+
+ b.add(v);
+
+ if (predicate.test(v)) {
+ buffer = b;
+ return true;
+ }
+ }
+
+ if (b.isEmpty()) {
+ done = true;
+ return false;
+ }
+
+ buffer = b;
+ done = true;
+ }
+ return true;
+ }
+
+ @Override
+ public List next() {
+ if (hasNext()) {
+ List b = buffer;
+ buffer = null;
+ return b;
+ }
+ throw new NoSuchElementException();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/src/main/java/ix/IxBufferWhile.java b/src/main/java/ix/IxBufferWhile.java
new file mode 100644
index 0000000..af28b81
--- /dev/null
+++ b/src/main/java/ix/IxBufferWhile.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2011-2016 David Karnok
+ *
+ * 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 ix;
+
+import java.util.*;
+
+/**
+ * Buffer while the predicate returns true.
+ *
+ * @param the value type
+ */
+final class IxBufferWhile extends IxSource> {
+
+ final IxPredicate super T> predicate;
+
+ IxBufferWhile(Iterable source, IxPredicate super T> predicate) {
+ super(source);
+ this.predicate = predicate;
+ }
+
+ @Override
+ public Iterator> iterator() {
+ return new BufferSplitIterator(source.iterator(), predicate);
+ }
+
+ static final class BufferSplitIterator implements Iterator> {
+
+ final Iterator source;
+
+ final IxPredicate super T> predicate;
+
+ boolean done;
+
+ List buffer;
+
+ List next;
+
+ BufferSplitIterator(Iterator source, IxPredicate super T> predicate) {
+ this.source = source;
+ this.predicate = predicate;
+ }
+
+ @Override
+ public boolean hasNext() {
+ List b = buffer;
+ if (b == null) {
+ if (done) {
+ return false;
+ }
+
+ b = next;
+ if (b == null) {
+ b = new ArrayList();
+ }
+
+ Iterator src = source;
+ while (src.hasNext()) {
+ T v = src.next();
+
+ if (!predicate.test(v)) {
+ buffer = b;
+ b = new ArrayList();
+ b.add(v);
+ next = b;
+ return true;
+ }
+
+ b.add(v);
+ }
+
+ if (b.isEmpty()) {
+ done = true;
+ return false;
+ }
+
+ buffer = b;
+ done = true;
+ }
+ return true;
+ }
+
+ @Override
+ public List next() {
+ if (hasNext()) {
+ List b = buffer;
+ buffer = null;
+ return b;
+ }
+ throw new NoSuchElementException();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/src/main/java/ix/IxEvery.java b/src/main/java/ix/IxEvery.java
new file mode 100644
index 0000000..7c510a2
--- /dev/null
+++ b/src/main/java/ix/IxEvery.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2011-2016 David Karnok
+ *
+ * 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 ix;
+
+import java.util.*;
+
+/**
+ * Emits every Nth item from upstream.
+ *
+ * @param the value type
+ */
+final class IxEvery extends IxSource {
+
+ final int nth;
+
+ IxEvery(Iterable source, int nth) {
+ super(source);
+ this.nth = nth;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new EveryIterator(source.iterator(), nth);
+ }
+
+ static final class EveryIterator implements Iterator {
+
+ final Iterator source;
+
+ final int nth;
+
+ boolean done;
+
+ boolean hasValue;
+
+ EveryIterator(Iterator it, int nth) {
+ this.source = it;
+ this.nth = nth;
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (done) {
+ return false;
+ }
+ if (!hasValue) {
+ int i = nth - 1;
+
+ Iterator src = source;
+
+ while (i != 0 && src.hasNext()) {
+ src.next();
+ i--;
+ }
+
+ if (src.hasNext()) {
+ hasValue = true;
+ return true;
+ }
+
+ done = true;
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public T next() {
+ if (hasNext()) {
+ hasValue = false;
+ return source.next();
+ }
+ throw new NoSuchElementException();
+ }
+
+ @Override
+ public void remove() {
+ source.remove();
+ }
+ }
+}
diff --git a/src/main/java/ix/IxOrderedMergeArray.java b/src/main/java/ix/IxOrderedMergeArray.java
new file mode 100644
index 0000000..ce895fa
--- /dev/null
+++ b/src/main/java/ix/IxOrderedMergeArray.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2011-2016 David Karnok
+ *
+ * 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 ix;
+
+import java.util.*;
+
+/**
+ * Merges an array of Iterable items by picking the smallest from them
+ * with the help of a Comparator.
+ *
+ * @param the value type
+ */
+final class IxOrderedMergeArray extends Ix {
+
+ final Iterable extends T>[] sources;
+
+ final Comparator super T> comparator;
+
+ IxOrderedMergeArray(Iterable extends T>[] sources, Comparator super T> comparator) {
+ this.sources = sources;
+ this.comparator = comparator;
+ }
+
+ @Override
+ public Iterator iterator() {
+ Iterable extends T>[] all = sources;
+ int n = all.length;
+ @SuppressWarnings("unchecked")
+ Iterator extends T>[] srcs = new Iterator[n];
+ for (int i = 0; i < n; i++) {
+ srcs[i] = all[i].iterator();
+ }
+ return new OrderedMergeIterator(srcs, n, comparator);
+ }
+
+ static final class OrderedMergeIterator implements Iterator {
+
+ final Iterator extends T>[] sources;
+
+ final Comparator super T> comparator;
+
+ final int n;
+
+ final Object[] latest;
+
+ static final Object EMPTY = new Object();
+
+ static final Object DONE = new Object();
+
+ boolean done;
+
+ int index;
+
+ OrderedMergeIterator(Iterator extends T>[] sources, int n, Comparator super T> comparator) {
+ this.sources = sources;
+ this.n = n;
+ this.latest = new Object[n];
+ Arrays.fill(latest, EMPTY);
+ this.comparator = comparator;
+ this.index = -1;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean hasNext() {
+ int i = index;
+ if (i < 0) {
+ if (done) {
+ return false;
+ }
+ int count = n;
+ Object[] vs = latest;
+ int d = 0;
+ int f = -1;
+ T min = null;
+ for (int j = 0; j < count; j++) {
+ Object o = vs[j];
+ if (o == DONE) {
+ d++;
+ continue;
+ } else
+ if (o == EMPTY) {
+ Iterator extends T> src = sources[j];
+ if (src.hasNext()) {
+ o = src.next();
+ vs[j] = o;
+ } else {
+ d++;
+ vs[j] = DONE;
+ continue;
+ }
+ }
+
+ if (f < 0 || comparator.compare(min, (T)o) > 0) {
+ f = j;
+ min = (T)o;
+ }
+ }
+
+ if (d == count) {
+ done = true;
+ return false;
+ }
+
+ index = f;
+ }
+ return true;
+ }
+
+ @Override
+ public T next() {
+ if (hasNext()) {
+ int i = index;
+ index = -1;
+ @SuppressWarnings("unchecked")
+ T v = (T)latest[i];
+ latest[i] = EMPTY;
+ return v;
+ }
+ throw new NoSuchElementException();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/src/main/java/ix/IxOrderedMergeIterable.java b/src/main/java/ix/IxOrderedMergeIterable.java
new file mode 100644
index 0000000..d5af595
--- /dev/null
+++ b/src/main/java/ix/IxOrderedMergeIterable.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2011-2016 David Karnok
+ *
+ * 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 ix;
+
+import java.util.*;
+
+import ix.IxOrderedMergeArray.OrderedMergeIterator;
+
+/**
+ * Merges an array of Iterable items by picking the smallest from them
+ * with the help of a Comparator.
+ *
+ * @param the value type
+ */
+final class IxOrderedMergeIterable extends Ix {
+
+ final Iterable extends Iterable extends T>> sources;
+
+ final Comparator super T> comparator;
+
+ IxOrderedMergeIterable(Iterable extends Iterable extends T>> sources, Comparator super T> comparator) {
+ this.sources = sources;
+ this.comparator = comparator;
+ }
+
+ @Override
+ public Iterator iterator() {
+ @SuppressWarnings("unchecked")
+ Iterator extends T>[] srcs = new Iterator[8];
+ int n = 0;
+
+ for (Iterable extends T> iter : sources) {
+ if (n == srcs.length) {
+ srcs = Arrays.copyOf(srcs, n + (n >> 2));
+ }
+ srcs[n++] = iter.iterator();
+ }
+
+ return new OrderedMergeIterator(srcs, n, comparator);
+ }
+}
diff --git a/src/main/java/ix/IxReadOnly.java b/src/main/java/ix/IxReadOnly.java
new file mode 100644
index 0000000..6850d90
--- /dev/null
+++ b/src/main/java/ix/IxReadOnly.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2011-2016 David Karnok
+ *
+ * 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 ix;
+
+import java.util.Iterator;
+
+/**
+ * Suppress or throw when the remove() is called.
+ *
+ * @param the value type
+ */
+final class IxReadOnly extends IxSource {
+
+ final boolean silent;
+
+ IxReadOnly(Iterable source, boolean silent) {
+ super(source);
+ this.silent = silent;
+ }
+
+ @Override
+ public Iterator iterator() {
+ if (silent) {
+ return new ReadOnlySilentIterator(source.iterator());
+ }
+ return new ReadOnlyThrowingIterator(source.iterator());
+ }
+
+ static final class ReadOnlySilentIterator implements Iterator {
+
+ final Iterator source;
+
+ ReadOnlySilentIterator(Iterator source) {
+ this.source = source;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return source.hasNext();
+ }
+
+ @Override
+ public T next() {
+ return source.next();
+ }
+
+ @Override
+ public void remove() {
+ // deliberately ignored
+ }
+ }
+
+ static final class ReadOnlyThrowingIterator implements Iterator {
+
+ final Iterator source;
+
+ ReadOnlyThrowingIterator(Iterator source) {
+ this.source = source;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return source.hasNext();
+ }
+
+ @Override
+ public T next() {
+ return source.next();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/src/main/java/ix/IxRepeat.java b/src/main/java/ix/IxRepeat.java
index c06f8f0..a30b998 100644
--- a/src/main/java/ix/IxRepeat.java
+++ b/src/main/java/ix/IxRepeat.java
@@ -18,7 +18,7 @@
import java.util.Iterator;
-final class IxRepeat extends Ix {
+final class IxRepeat extends Ix implements Iterator {
final T value;
@@ -28,30 +28,21 @@ final class IxRepeat extends Ix {
@Override
public Iterator iterator() {
- return new RepeatIterator(value);
+ return this;
}
- static final class RepeatIterator implements Iterator {
-
- final T value;
-
- RepeatIterator(T value) {
- this.value = value;
- }
-
- @Override
- public boolean hasNext() {
- return true;
- }
+ @Override
+ public boolean hasNext() {
+ return true;
+ }
- @Override
- public T next() {
- return value;
- }
+ @Override
+ public T next() {
+ return value;
+ }
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
}
}
diff --git a/src/main/java/ix/IxRepeatCallable.java b/src/main/java/ix/IxRepeatCallable.java
new file mode 100644
index 0000000..1587466
--- /dev/null
+++ b/src/main/java/ix/IxRepeatCallable.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2011-2016 David Karnok
+ *
+ * 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 ix;
+
+import java.util.Iterator;
+import java.util.concurrent.Callable;
+
+/**
+ * Repeatedly call a Callable indefinitely.
+ *
+ * @param the value type
+ */
+final class IxRepeatCallable extends Ix implements Iterator {
+
+ final Callable callable;
+
+ IxRepeatCallable(Callable callable) {
+ this.callable = callable;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return this;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return true;
+ }
+
+ @Override
+ public T next() {
+ return checkedCall(callable);
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/src/test/java/ix/BufferPredicateTest.java b/src/test/java/ix/BufferPredicateTest.java
new file mode 100644
index 0000000..c71f4dd
--- /dev/null
+++ b/src/test/java/ix/BufferPredicateTest.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2011-2016 David Karnok
+ *
+ * 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 ix;
+
+import java.util.*;
+
+import org.junit.Test;
+
+public class BufferPredicateTest {
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void splitNormal() {
+ Ix> source = Ix.fromArray(1, 2, 10, 3, 10, 4)
+ .bufferSplit(new IxPredicate() {
+ @Override
+ public boolean test(Integer v) {
+ return v == 10;
+ }
+ });
+
+ IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(3), Arrays.asList(4));
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void splitNormalEmpty() {
+ Ix> source = Ix.fromArray(1, 2, 10, 10)
+ .bufferSplit(new IxPredicate() {
+ @Override
+ public boolean test(Integer v) {
+ return v == 10;
+ }
+ });
+
+ IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList());
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void whileNormal() {
+ Ix> source = Ix.fromArray(1, 2, 10, 3, 10, 4)
+ .bufferWhile(new IxPredicate() {
+ @Override
+ public boolean test(Integer v) {
+ return v != 10;
+ }
+ });
+
+ IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(10, 3), Arrays.asList(10, 4));
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void whileNormalEmpty() {
+ Ix> source = Ix.fromArray(1, 2, 10, 10)
+ .bufferWhile(new IxPredicate() {
+ @Override
+ public boolean test(Integer v) {
+ return v != 10;
+ }
+ });
+
+ IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(10), Arrays.asList(10));
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void untilNormal() {
+ Ix> source = Ix.fromArray(1, 2, 10, 3, 10, 4)
+ .bufferUntil(new IxPredicate() {
+ @Override
+ public boolean test(Integer v) {
+ return v == 10;
+ }
+ });
+
+ IxTestHelper.assertValues(source, Arrays.asList(1, 2, 10), Arrays.asList(3, 10), Arrays.asList(4));
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void untilNormalEmpty() {
+ Ix> source = Ix.fromArray(1, 2, 10, 10)
+ .bufferUntil(new IxPredicate() {
+ @Override
+ public boolean test(Integer v) {
+ return v == 10;
+ }
+ });
+
+ IxTestHelper.assertValues(source, Arrays.asList(1, 2, 10), Arrays.asList(10));
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void splitEmpty() {
+ Ix> source = Ix.empty().bufferSplit(new IxPredicate() {
+ @Override
+ public boolean test(Integer v) {
+ return v == 10;
+ }
+ });
+
+ IxTestHelper.assertValues(source);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void whileEmpty() {
+ Ix> source = Ix.empty().bufferWhile(new IxPredicate() {
+ @Override
+ public boolean test(Integer v) {
+ return v != 10;
+ }
+ });
+
+ IxTestHelper.assertValues(source);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void untilEmpty() {
+ Ix> source = Ix.empty().bufferUntil(new IxPredicate() {
+ @Override
+ public boolean test(Integer v) {
+ return v == 10;
+ }
+ });
+
+ IxTestHelper.assertValues(source);
+ }
+}
diff --git a/src/test/java/ix/EveryTest.java b/src/test/java/ix/EveryTest.java
new file mode 100644
index 0000000..b8f2b06
--- /dev/null
+++ b/src/test/java/ix/EveryTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2011-2016 David Karnok
+ *
+ * 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 ix;
+
+import java.util.*;
+
+import org.junit.*;
+
+public class EveryTest {
+
+ @Test
+ public void normal() {
+ Ix source = Ix.range(1, 5).every(2);
+
+ IxTestHelper.assertValues(source, 2, 4);
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @Test
+ public void normal2() {
+ Ix source = Ix.range(1, 5).every(1);
+
+ IxTestHelper.assertValues(source, 1, 2, 3, 4, 5);
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @Test
+ public void normal3() {
+ Ix source = Ix.range(1, 5).every(10);
+
+ IxTestHelper.assertValues(source);
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @Test
+ public void remove() {
+ List list = new ArrayList();
+ list.add(1);
+ list.add(2);
+ list.add(3);
+ list.add(4);
+ list.add(5);
+
+ Ix.from(list).every(2).removeAll();
+
+ Assert.assertEquals(Arrays.asList(1, 3, 5), list);
+ }
+}
diff --git a/src/test/java/ix/OrderedMergeTest.java b/src/test/java/ix/OrderedMergeTest.java
new file mode 100644
index 0000000..4038293
--- /dev/null
+++ b/src/test/java/ix/OrderedMergeTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2011-2016 David Karnok
+ *
+ * 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 ix;
+
+import java.util.Comparator;
+
+import org.junit.Test;
+
+public class OrderedMergeTest {
+
+ @Test
+ public void normalArray() {
+ @SuppressWarnings("unchecked")
+ Ix source = Ix.orderedMergeArray(Ix.fromArray(1, 3), Ix.fromArray(2, 4, 5));
+
+ IxTestHelper.assertValues(source, 1, 2, 3, 4, 5);
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @Test
+ public void normalIterable() {
+ @SuppressWarnings("unchecked")
+ Ix source = Ix.orderedMerge(Ix.fromArray(Ix.fromArray(1, 3), Ix.fromArray(2, 4, 5)));
+
+ IxTestHelper.assertValues(source, 1, 2, 3, 4, 5);
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void firstEmptyArray() {
+ Ix source = Ix.orderedMergeArray(Ix.empty(), Ix.fromArray(2, 4, 5));
+
+ IxTestHelper.assertValues(source, 2, 4, 5);
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void secondEmptyArray() {
+ Ix source = Ix.orderedMergeArray(Ix.fromArray(1, 3), Ix.empty());
+
+ IxTestHelper.assertValues(source, 1, 3);
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void bothEmptyArray() {
+ Ix source = Ix.orderedMergeArray(Ix.empty(), Ix.empty());
+
+ IxTestHelper.assertValues(source);
+ }
+
+ @Test
+ public void comparatorArray() {
+ @SuppressWarnings("unchecked")
+ Ix source = Ix.orderedMergeArray(
+ new Comparator() {
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return o2.compareTo(o1);
+ }
+ },
+ Ix.fromArray(3, 1), Ix.fromArray(5, 4, 2));
+
+ IxTestHelper.assertValues(source, 5, 4, 3, 2, 1);
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @Test
+ public void comparatorIterable() {
+ @SuppressWarnings("unchecked")
+ Ix source = Ix.orderedMerge(Ix.fromArray(Ix.fromArray(3, 1), Ix.fromArray(5, 4, 2)),
+ new Comparator() {
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return o2.compareTo(o1);
+ }
+ }
+ );
+
+ IxTestHelper.assertValues(source, 5, 4, 3, 2, 1);
+ IxTestHelper.assertNoRemove(source);
+ }
+
+ @Test
+ public void lotsOfIterables() {
+ Ix source = Ix.orderedMerge(Ix.repeatValue(Ix.just(1), 30)).sumInt();
+
+ IxTestHelper.assertValues(source, 30);
+ }
+}
diff --git a/src/test/java/ix/ReadOnlyTest.java b/src/test/java/ix/ReadOnlyTest.java
new file mode 100644
index 0000000..98384ab
--- /dev/null
+++ b/src/test/java/ix/ReadOnlyTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2011-2016 David Karnok
+ *
+ * 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 ix;
+
+import java.util.*;
+
+import org.junit.*;
+
+public class ReadOnlyTest {
+
+ @Test
+ public void normal() {
+ List list = new ArrayList();
+ list.add(1);
+ list.add(2);
+ list.add(3);
+
+ Ix source = Ix.from(list).readOnly();
+
+ IxTestHelper.assertValues(source, 1, 2, 3);
+ IxTestHelper.assertNoRemove(source);
+
+ Assert.assertEquals(3, list.size());
+ }
+
+ @Test
+ public void normalSilent() {
+ List list = new ArrayList();
+ list.add(1);
+ list.add(2);
+ list.add(3);
+
+ Ix source = Ix.from(list).readOnly(true);
+
+ IxTestHelper.assertValues(source, 1, 2, 3);
+
+ source.removeAll();
+
+ Assert.assertEquals(3, list.size());
+
+ IxTestHelper.assertValues(source, 1, 2, 3);
+ }
+}
diff --git a/src/test/java/ix/RepeatTest.java b/src/test/java/ix/RepeatTest.java
index 0f9da8a..e3c8ee7 100644
--- a/src/test/java/ix/RepeatTest.java
+++ b/src/test/java/ix/RepeatTest.java
@@ -16,6 +16,8 @@
package ix;
+import java.util.concurrent.Callable;
+
import org.junit.Test;
public class RepeatTest {
@@ -237,4 +239,19 @@ public boolean getAsBoolean() {
IxTestHelper.assertNoRemove(source);
}
+
+ @Test
+ public void repeatCallable() {
+ Ix source = Ix.repeatCallable(new Callable() {
+ @Override
+ public Integer call() throws Exception {
+ return 1;
+ }
+ })
+ .take(5);
+
+ IxTestHelper.assertValues(source, 1, 1, 1, 1, 1);
+
+ IxTestHelper.assertNoRemove(source);
+ }
}