// Problem reported by DMZ on 10/30
/**
* Implements a doubly linked list.
*
* @author Kevin Vigue
* @version 9/18/2013
* @param <T> Type stored in list.
*/
public class DoublyLinkedList<T>
{
/**
* The linked list node after this one.
*
* @author Kevin Vigue
* @version 9/18/2013
*/
/*@ nullable spec_public */ private DoublyLinkedList<T> my_next;
/**
* The linked list node before this one.
*
* @author Kevin Vigue
* @version 9/18/2013
*/
/*@ nullable spec_public */ private DoublyLinkedList<T> my_prev;
/**
* The value stored in this linked list node.
*
* @author Kevin Vigue
* @version 9/18/2013
*/
/*@ nullable spec_public */ private T my_value;
//@ public invariant my_next != this;
//@ public invariant my_prev != this;
//@ public invariant my_next != null ==> my_next != my_prev;
/**
* Constructor that takes a value.
*
* @author Kevin Vigue
* @version 9/18/2013
* @param a_value Data to be stored in my_value.
*/
public DoublyLinkedList(final T a_value)
{
my_next = null;
my_prev = null;
my_value = a_value;
}
/**
* Constructor that lets you specify my_prev, my_value, and my_next.
*
* @author Kevin Vigue
* @version 9/18/2013
* @param a_prev Doubly linked list that comes before this one.
* @param a_value Value to be stored in this node.
* @param a_next Doubly linked list that comes after this one.
*/
//@ requires a_prev != this && a_next != this && (a_next != null ==> a_next != a_prev);
public DoublyLinkedList(final DoublyLinkedList<T> a_prev, final T a_value,
final DoublyLinkedList<T> a_next)
{
my_next = a_next;
my_prev = a_prev;
my_value = a_value;
}
/**
* Getter for my_value.
*
* @author Kevin Vigue
* @version 9/18/2013
* @return The value in this node.
*/
/*@ nullable */
public T getValue()
{
return my_value;
}
/**
* Setter for my_value.
*
* @author Kevin Vigue
* @version 9/18/2013
* @param a_value New value for this node.
*/
//@ assignable my_value;
//@ ensures my_value == a_value;
public void setValue(/*@ nullable */ final T a_value)
{
my_value = a_value;
}
/**
* Getter for my_prev.
*
* @author Kevin Vigue
* @version 9/18/2013
* @return The doubly linked list before this one.
*/
/*@ nullable */
public DoublyLinkedList<T> getPrev()
{
return my_prev;
}
/**
* Setter for my_prev.
*
* @author Kevin Vigue
* @version 9/18/2013
* @param a_doubly_linked_list New node to come before this one.
*/
//@ requires this != a_doubly_linked_list && (my_next != null ==> a_doubly_linked_list != my_next);
//@ assignable my_prev;
//@ ensures my_prev == a_doubly_linked_list;
public void setPrev(/*@ nullable */ final DoublyLinkedList<T> a_doubly_linked_list)
{
// A doubly linked list's next is not itself.
assert a_doubly_linked_list != this : "Attempt to set prev to self.";
my_prev = a_doubly_linked_list;
}
/**
* Getter for my_next.
*
* @author Kevin Vigue
* @version 9/18/2013
* @return The doubly linked list after this one.
*/
/*@ nullable */
public DoublyLinkedList<T> getNext()
{
return my_next;
}
/**
* Setter for my_next.
*
* @author Kevin Vigue
* @version 9/18/2013
* @param a_doubly_linked_list New node to come after this one.
*/
//@ requires this != a_doubly_linked_list && (a_doubly_linked_list != null ==> a_doubly_linked_list != my_prev);
//@ assignable my_next;
//@ ensures my_next == a_doubly_linked_list;
public void setNext(/*@ nullable */ final DoublyLinkedList<T> a_doubly_linked_list)
{
// A doubly linked list's prev is not itself.
assert a_doubly_linked_list != this : "Attempt to set next to self.";
my_next = a_doubly_linked_list;
}
/**
* Removes this node from the larger doubly linked list structure.
*
* @author Kevin Vigue
* @version 9/18/2013
*/
//@ requires my_prev != null && my_next != null;
//@ requires my_prev != my_next.my_next;
//@ requires my_prev.my_prev != my_next;
public void remove()
{
if (my_prev != null)
{
my_prev.setNext(my_next);
}
if (my_next != null)
{
my_next.setPrev(my_prev);
}
}
}