summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/data
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/bjc/data')
-rw-r--r--src/main/java/bjc/data/Contexts.java96
-rw-r--r--src/main/java/bjc/data/GeneratingIterator.java2
-rw-r--r--src/main/java/bjc/data/MarkListIterator.java175
-rw-r--r--src/main/java/bjc/data/Multimap.java16
-rw-r--r--src/main/java/bjc/data/Pair.java14
-rw-r--r--src/main/java/bjc/data/ResettableIterator.java14
6 files changed, 244 insertions, 73 deletions
diff --git a/src/main/java/bjc/data/Contexts.java b/src/main/java/bjc/data/Contexts.java
index b028ad1..f587fe6 100644
--- a/src/main/java/bjc/data/Contexts.java
+++ b/src/main/java/bjc/data/Contexts.java
@@ -37,67 +37,67 @@ public class Contexts {
public static Context create(Context parent) {
return new ContextImpl(parent);
}
+}
- private static class NullContextImpl implements Context {
- @Override
- public Context getParent() {
- return this;
- }
+class NullContextImpl implements Context {
+ @Override
+ public Context getParent() {
+ return this;
+ }
- @Override
- public void register(String name, Object o) {
- throw new UnsupportedOperationException();
- }
+ @Override
+ public void register(String name, Object o) {
+ throw new UnsupportedOperationException();
+ }
- @Override
- public Object get(String name) {
- throw new NoSuchElementException();
- }
-
- @Override
- public <T> T get(Class<T> contract) {
- throw new NoSuchElementException();
- }
+ @Override
+ public Object get(String name) {
+ throw new NoSuchElementException();
}
+
+ @Override
+ public <T> T get(Class<T> contract) {
+ throw new NoSuchElementException();
+ }
+}
- private static class ContextImpl implements Context {
+class ContextImpl implements Context {
- private final Context parent;
+ private final Context parent;
- private final Map<String, Object> objects;
+ private final Map<String, Object> objects;
- public ContextImpl(Context parent) {
- this.parent = parent;
- this.objects = new HashMap<>();
- }
+ public ContextImpl(Context parent) {
+ this.parent = parent;
+ this.objects = new HashMap<>();
+ }
- @Override
- public void register(String name, Object o) {
- objects.put(name, o);
- }
+ @Override
+ public void register(String name, Object o) {
+ objects.put(name, o);
+ }
- @Override
- public Object get(String name) {
- if (objects.containsKey(name)) {
- return objects.get(name);
- }
- return parent.get(name);
+ @Override
+ public Object get(String name) {
+ if (objects.containsKey(name)) {
+ return objects.get(name);
}
+ return parent.get(name);
+ }
- @SuppressWarnings("unchecked")
- @Override
- public <T> T get(Class<T> contract) {
- for (Object o : objects.values()) {
- if (contract.isInstance(o)) {
- return (T) o;
- }
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T get(Class<T> contract) {
+ for (Object o : objects.values()) {
+ if (contract.isInstance(o)) {
+ return (T) o;
}
- return parent.get(contract);
}
+ return parent.get(contract);
+ }
- @Override
- public Context getParent() {
- return parent;
- }
+ @Override
+ public Context getParent() {
+ return parent;
}
-}
+} \ No newline at end of file
diff --git a/src/main/java/bjc/data/GeneratingIterator.java b/src/main/java/bjc/data/GeneratingIterator.java
index f926833..8900b94 100644
--- a/src/main/java/bjc/data/GeneratingIterator.java
+++ b/src/main/java/bjc/data/GeneratingIterator.java
@@ -42,7 +42,7 @@ public class GeneratingIterator<E> implements Iterator<E> {
@Override
public boolean hasNext() {
- return stpper.test(state);
+ return !stpper.test(state);
}
/*
diff --git a/src/main/java/bjc/data/MarkListIterator.java b/src/main/java/bjc/data/MarkListIterator.java
new file mode 100644
index 0000000..35baa28
--- /dev/null
+++ b/src/main/java/bjc/data/MarkListIterator.java
@@ -0,0 +1,175 @@
+package bjc.data;
+
+import java.util.*;
+
+/**
+ * ListIterator which allows navigation/marking of an iterator.
+ *
+ * @author bjcul
+ *
+ * @param <E> The element type
+ */
+public class MarkListIterator<E> implements ListIterator<E> {
+ private Iterator<E> backing;
+
+ private List<E> cache;
+ private Deque<Integer> marks;
+
+ private int currIdx;
+ private int maxIdx;
+
+ /**
+ * Create a new marking list iterator.
+ *
+ * @param backing The iterator which backs us.
+ */
+ public MarkListIterator(Iterator<E> backing) {
+ this.backing = backing;
+
+ this.currIdx = 0;
+ this.maxIdx = 0;
+
+ this.cache = new ArrayList<>();
+ this.marks = new ArrayDeque<>();
+ }
+
+ /**
+ * Get the current element of the iterator.
+ *
+ * @return The current iterator of the element
+ */
+ public E current() {
+ return cache.get(currIdx);
+ }
+
+ /**
+ * Create a new marking list iterator.
+ *
+ * @param backing The iterable to get the backing iterator from.
+ */
+ public MarkListIterator(Iterable<E> backing) {
+ this(backing.iterator());
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (currIdx < maxIdx)
+ return true;
+ return backing.hasNext();
+ }
+
+ @Override
+ public E next() {
+ if (currIdx < maxIdx) {
+ return cache.get(currIdx++);
+ }
+ currIdx++;
+ maxIdx++;
+ E next = backing.next();
+ cache.add(next);
+ return next;
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return maxIdx > 0 && currIdx > 0;
+ }
+
+ @Override
+ public E previous() {
+ currIdx--;
+ return cache.get(currIdx);
+ }
+
+ @Override
+ public int nextIndex() {
+ return currIdx + 1;
+ }
+
+ @Override
+ public int previousIndex() {
+ return currIdx - 1;
+ }
+
+ /**
+ * Mark the current position in the iterator.
+ */
+ public void mark() {
+ marks.push(currIdx);
+ }
+
+ /**
+ * Reset the iterator to the last position that was marked, leaving the mark in
+ * place.
+ *
+ * @return Whether or not a rollback actually happened
+ */
+ public boolean rollback() {
+ return rollback(false);
+ }
+
+ /**
+ * Reset the iterator to the last position that was marked.
+ *
+ * @param clearMark Whether to clear the mark being rolled back to.
+ *
+ * @return Whether or not a rollback actually happened
+ */
+ public boolean rollback(boolean clearMark) {
+ if (marks.isEmpty()) return false;
+
+ if (clearMark) {
+ currIdx = marks.pop();
+ } else {
+ currIdx = marks.peek();
+ }
+ return true;
+ }
+
+ /**
+ * Remove the last position that was marked.
+ *
+ * @return The marked position
+ */
+ public int commit() {
+ return marks.pop();
+ }
+
+ /**
+ * Resets the cache state of this iterator.
+ *
+ * Once this has been called, all of the previous elements and marks are
+ * discarded.
+ */
+ public void reset() {
+ this.cache = new ArrayList<>();
+ this.marks = new ArrayDeque<>();
+
+ this.currIdx = 0;
+ this.maxIdx = 0;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Can't remove items");
+ }
+
+ @Override
+ public void set(E e) {
+ throw new UnsupportedOperationException("Can't set items");
+ }
+
+ @Override
+ public void add(E e) {
+ throw new UnsupportedOperationException("Can't add items");
+ }
+
+ /**
+ * Check if this iterator has at least one active mark.
+ *
+ * @return Whether this iterator has any active marks.
+ */
+ public boolean hasMark() {
+ return !marks.isEmpty();
+ }
+}
diff --git a/src/main/java/bjc/data/Multimap.java b/src/main/java/bjc/data/Multimap.java
deleted file mode 100644
index 0e858b7..0000000
--- a/src/main/java/bjc/data/Multimap.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package bjc.data;
-
-/**
- * A map with support for multiple values per key.
- *
- * @param <KeyType>
- * The type of the keys for the map.
- * @param <ValueType>
- * The type of the values for the map.
- *
- * @author Ben Culkin
- */
-public class Multimap<KeyType, ValueType> {
- // TODO either implement this, or find if there is an implementation I've
- // written elsewhere
-}
diff --git a/src/main/java/bjc/data/Pair.java b/src/main/java/bjc/data/Pair.java
index baf1894..1d4be5e 100644
--- a/src/main/java/bjc/data/Pair.java
+++ b/src/main/java/bjc/data/Pair.java
@@ -1,5 +1,8 @@
package bjc.data;
+import java.util.Formattable;
+import java.util.FormattableFlags;
+import java.util.Formatter;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
@@ -18,7 +21,7 @@ import bjc.funcdata.theory.Bifunctor;
* The type of the right side of the pair.
*
*/
-public interface Pair<LeftType, RightType> extends Bifunctor<LeftType, RightType> {
+public interface Pair<LeftType, RightType> extends Bifunctor<LeftType, RightType>, Formattable {
/**
* Bind a function across the values in this pair.
*
@@ -247,4 +250,13 @@ public interface Pair<LeftType, RightType> extends Bifunctor<LeftType, RightType
public static <Left, Right> Pair<Left, Right> pair(Left left, Right right) {
return new SimplePair<>(left, right);
}
+
+ @Override
+ default void formatTo(Formatter formatter, int flags, int width, int precision) {
+ if ((flags & FormattableFlags.ALTERNATE) != 0) {
+ formatter.format("(%s, %s)", getLeft(), getRight());
+ } else {
+ formatter.format("Pair [l=%s, r=%s", getLeft(), getRight());
+ }
+ }
}
diff --git a/src/main/java/bjc/data/ResettableIterator.java b/src/main/java/bjc/data/ResettableIterator.java
index 8b7f07a..8c1c4aa 100644
--- a/src/main/java/bjc/data/ResettableIterator.java
+++ b/src/main/java/bjc/data/ResettableIterator.java
@@ -5,12 +5,12 @@ import java.util.*;
/*
* @TODO Oct 6, 2020 - Ben Culkin - :CleverCache
*
- * In the future, there are certain efficencies we could take with our cached
+ * In the future, there are certain efficiencies we could take with our cached
* elements; namely, the case where we repeat the same element multiple times,
* or the case where we have a mixture of identical (and probably sizable) elements
*
- * The general downside to these of course, is that these efficencies would cost
- * us something in terms of complexity, as well as not benefitting iterators which
+ * The general downside to these of course, is that these efficiencies would cost
+ * us something in terms of complexity, as well as not benefiting iterators which
* aren't large enough.
*
* Still an interesting thought as to the best way to implement such a thing though.
@@ -57,7 +57,7 @@ public class ResettableIterator<T> implements Iterator<T> {
@Override
public boolean hasNext() {
if (isRepeating) return cacheIterator.hasNext() ? true : backing.hasNext();
- else return backing.hasNext();
+ return backing.hasNext();
}
@Override
@@ -65,10 +65,10 @@ public class ResettableIterator<T> implements Iterator<T> {
if (isRepeating) {
if (cacheIterator.hasNext()) {
return cacheIterator.next();
- } else {
- cacheIterator = null;
- isRepeating = false;
}
+
+ cacheIterator = null;
+ isRepeating = false;
}
T itm = backing.next();