001 // Copyright 2007 Waterken Inc. under the terms of the MIT X license
002 // found at http://www.opensource.org/licenses/mit-license.html
003 package org.ref_send.list;
004
005 import static org.ref_send.promise.Eventual.near;
006 import static org.ref_send.promise.Eventual.ref;
007
008 import java.io.Serializable;
009 import java.util.Iterator;
010 import java.util.NoSuchElementException;
011
012 import org.joe_e.Equatable;
013 import org.joe_e.Struct;
014 import org.ref_send.promise.Promise;
015 import org.ref_send.promise.Receiver;
016
017 /**
018 * A linked list.
019 * @param <T> element type
020 */
021 public final class
022 List<T> implements Iterable<T>, Serializable {
023 static private final long serialVersionUID = 1L;
024
025 static protected final class
026 Link<T> implements Equatable, Serializable {
027 static private final long serialVersionUID = 1L;
028
029 protected Promise<Link<T>> next;
030 protected T value;
031 }
032
033 /**
034 * first element link
035 */
036 protected Promise<Link<T>> first;
037
038 /**
039 * first unused link
040 */
041 protected Link<T> last;
042
043 /**
044 * link count
045 */
046 private long capacity;
047
048 /**
049 * element count
050 */
051 private long size;
052
053 private
054 List() {
055 last = new Link<T>();
056 last.next = ref(last);
057 first = last.next;
058 capacity = 1;
059 size = 0;
060 }
061
062 /**
063 * Constructs a list.
064 * @param <T> element type
065 */
066 static public <T> List<T>
067 list() { return new List<T>(); }
068
069 // java.lang.Iterable interface
070
071 /**
072 * Iterates over the values in this list.
073 * @return forward iterator over this list
074 */
075 public final Iterator<T>
076 iterator() { return new IteratorX(); }
077
078 protected final class
079 IteratorX implements Iterator<T>, Serializable {
080 static private final long serialVersionUID = 1L;
081
082 private Link<T> current = near(first);
083
084 public boolean
085 hasNext() { return current != last; }
086
087 public T
088 next() {
089 if (current == last) { throw new NoSuchElementException(); }
090 final T r = current.value;
091 current = near(current.next);
092 return r;
093 }
094
095 public void
096 remove() { throw new UnsupportedOperationException(); }
097 }
098
099 // org.ref_send.list.List interface
100
101 /**
102 * Is the element count zero?
103 */
104 public boolean
105 isEmpty() { return 0 == size; }
106
107 /**
108 * Gets the element count.
109 */
110 public long
111 getSize() { return size; }
112
113 /**
114 * Gets the front value.
115 * @return front value
116 * @throws NullPointerException list is empty
117 */
118 public T
119 getFront() throws NullPointerException {
120 if (0 == size) { throw new NullPointerException(); }
121 return near(first).value;
122 }
123
124 /**
125 * Removes the front element.
126 * @return removed value
127 * @throws NullPointerException list is empty
128 */
129 public T
130 pop() throws NullPointerException {
131 if (0 == size) { throw new NullPointerException(); }
132 final Link<T> x = near(first);
133 final T r = x.value;
134 x.value = null;
135 first = x.next;
136 size -= 1;
137 return r;
138 }
139
140 /**
141 * Appends a value.
142 * @param value value to append
143 */
144 public void
145 append(final T value) {
146 last.value = value;
147 size += 1;
148 if (capacity == size) {
149 final Link<T> spare = new Link<T>();
150 spare.next = last.next;
151 last.next = ref(spare);
152 capacity += 1;
153 }
154 last = near(last.next);
155 }
156
157 /**
158 * Constructs an {@linkplain #append append}er.
159 */
160 public Receiver<T>
161 appender() { return new Appender(); }
162
163 protected final class
164 Appender extends Struct implements Receiver<T>, Serializable {
165 static private final long serialVersionUID = 1L;
166
167 public void
168 apply(final T value) { append(value); }
169 }
170 }