summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/esodata/DoubleTape.java
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2019-07-02 18:05:22 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2019-07-02 18:05:22 -0400
commit843329de434bb334d90927c4d22345373a388530 (patch)
treeb0ad1f764bd29ff43841e1095a5b58194c20cb37 /src/main/java/bjc/esodata/DoubleTape.java
parentac36f171a3cebb0993cc28548635e3f654f8e325 (diff)
Rename package root
The package root is now bjc, not io.github.bculkin2442.
Diffstat (limited to 'src/main/java/bjc/esodata/DoubleTape.java')
-rw-r--r--src/main/java/bjc/esodata/DoubleTape.java189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/main/java/bjc/esodata/DoubleTape.java b/src/main/java/bjc/esodata/DoubleTape.java
new file mode 100644
index 0000000..c36fcff
--- /dev/null
+++ b/src/main/java/bjc/esodata/DoubleTape.java
@@ -0,0 +1,189 @@
+package bjc.esodata;
+
+/**
+ * Double-sided tape is essentially two tapes stuck together with a shared
+ * cursor.
+ *
+ * The main way a double-sided tape differs is that it can be flipped, allowing
+ * access to another set of data.
+ *
+ * However, there is only one cursor, and the position of the cursor on one side
+ * is the inverse of the position on the other side.
+ *
+ * When one side is extended, a null will be inserted into the inactive side
+ * regardless of the auto-extension policy of the tape. The policy will still be
+ * respected for the active side.
+ *
+ * All operations that refer to the tape refer to the currently active side of
+ * the tape, except for flip.
+ *
+ * Flip refers to the entire tape for 'obvious' reasons.
+ *
+ * @param <T>
+ * The element type of the tape.
+ *
+ * @author bjculkin
+ */
+public class DoubleTape<T> implements Tape<T>, DoubleSided {
+ private boolean frontActive;
+
+ /* The front-side of the tape. */
+ private Tape<T> front;
+ /* The back-side of the tape. */
+ private Tape<T> back;
+
+ /** Create a new empty double-sided tape that doesn't autoextend. */
+ public DoubleTape() {
+ this(false);
+ }
+
+ /**
+ * Create a new empty double-sided tape that follows the specified
+ * auto-extension policy.
+ *
+ * @param autoExtnd
+ * Whether or not to auto-extend the tape to the right w/ nulls.
+ */
+ public DoubleTape(final boolean autoExtnd) {
+ front = new SingleTape<>(autoExtnd);
+ back = new SingleTape<>(autoExtnd);
+
+ frontActive = true;
+ }
+
+ @Override
+ public T item() {
+ return front.item();
+ }
+
+ @Override
+ public void item(final T itm) {
+ front.item(itm);
+ }
+
+ @Override
+ public int size() {
+ return front.size();
+ }
+
+ @Override
+ public int position() {
+ return front.position();
+ }
+
+ @Override
+ public void insertBefore(final T itm) {
+ front.insertBefore(itm);
+ back.insertAfter(null);
+ }
+
+ @Override
+ public void insertAfter(final T itm) {
+ front.insertAfter(itm);
+ back.insertBefore(itm);
+ }
+
+ @Override
+ public T remove() {
+ back.remove();
+
+ return front.remove();
+ }
+
+ @Override
+ public void first() {
+ front.first();
+ back.last();
+ }
+
+ @Override
+ public void last() {
+ front.last();
+ back.first();
+ }
+
+ @Override
+ public boolean left() {
+ return left(1);
+ }
+
+ @Override
+ public boolean left(final int amt) {
+ final boolean succ = front.left(amt);
+
+ if(succ) {
+ back.right(amt);
+ }
+
+ return succ;
+ }
+
+ @Override
+ public boolean right() {
+ return right(1);
+ }
+
+ @Override
+ public boolean right(final int amt) {
+ final boolean succ = front.right(amt);
+
+ if(succ) {
+ back.left(amt);
+ }
+
+ return succ;
+ }
+
+ public boolean seekTo(int tgtPos) {
+ return front.seekTo(tgtPos);
+ }
+
+ @Override
+ public void flip() {
+ final Tape<T> tmp = front;
+
+ front = back;
+
+ back = tmp;
+
+ frontActive = !frontActive;
+ }
+
+ @Override
+ public boolean currentSide() {
+ return frontActive;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (back == null ? 0 : back.hashCode());
+ result = prime * result + (front == null ? 0 : front.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if(this == obj) return true;
+ if(obj == null) return false;
+ if(!(obj instanceof DoubleTape<?>)) return false;
+
+ final DoubleTape<?> other = (DoubleTape<?>) obj;
+
+ if(back == null) {
+ if(other.back != null) return false;
+ } else if(!back.equals(other.back)) return false;
+
+ if(front == null) {
+ if(other.front != null) return false;
+ } else if(!front.equals(other.front)) return false;
+
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("DoubleTape [front=%s, back=%s]", front, back);
+ }
+}