Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: corelib/src/implementation/queue.dart

Issue 10890030: Move core and coreimpl from corelib/ to lib/core and lib/coreimpl. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « corelib/src/implementation/print.dart ('k') | corelib/src/implementation/regexp.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5
6 /**
7 * An entry in a doubly linked list. It contains a pointer to the next
8 * entry, the previous entry, and the boxed element.
9 */
10 class DoubleLinkedQueueEntry<E> {
11 DoubleLinkedQueueEntry<E> _previous;
12 DoubleLinkedQueueEntry<E> _next;
13 E _element;
14
15 DoubleLinkedQueueEntry(E e) {
16 _element = e;
17 }
18
19 void _link(DoubleLinkedQueueEntry<E> p,
20 DoubleLinkedQueueEntry<E> n) {
21 _next = n;
22 _previous = p;
23 p._next = this;
24 n._previous = this;
25 }
26
27 void append(E e) {
28 new DoubleLinkedQueueEntry<E>(e)._link(this, _next);
29 }
30
31 void prepend(E e) {
32 new DoubleLinkedQueueEntry<E>(e)._link(_previous, this);
33 }
34
35 E remove() {
36 _previous._next = _next;
37 _next._previous = _previous;
38 _next = null;
39 _previous = null;
40 return _element;
41 }
42
43 DoubleLinkedQueueEntry<E> _asNonSentinelEntry() {
44 return this;
45 }
46
47 DoubleLinkedQueueEntry<E> previousEntry() {
48 return _previous._asNonSentinelEntry();
49 }
50
51 DoubleLinkedQueueEntry<E> nextEntry() {
52 return _next._asNonSentinelEntry();
53 }
54
55 E get element() {
56 return _element;
57 }
58
59 void set element(E e) {
60 _element = e;
61 }
62 }
63
64 /**
65 * A sentinel in a double linked list is used to manipulate the list
66 * at both ends. A double linked list has exactly one sentinel, which
67 * is the only entry when the list is constructed. Initially, a
68 * sentinel has its next and previous entry point to itself. A
69 * sentinel does not box any user element.
70 */
71 class _DoubleLinkedQueueEntrySentinel<E> extends DoubleLinkedQueueEntry<E> {
72 _DoubleLinkedQueueEntrySentinel() : super(null) {
73 _link(this, this);
74 }
75
76 E remove() {
77 throw const EmptyQueueException();
78 }
79
80 DoubleLinkedQueueEntry<E> _asNonSentinelEntry() {
81 return null;
82 }
83
84 void set element(E e) {
85 // This setter is unreachable.
86 assert(false);
87 }
88
89 E get element() {
90 throw const EmptyQueueException();
91 }
92 }
93
94 /**
95 * Implementation of a double linked list that box list elements into
96 * DoubleLinkedQueueEntry objects.
97 */
98 class DoubleLinkedQueue<E> implements Queue<E> {
99 _DoubleLinkedQueueEntrySentinel<E> _sentinel;
100
101 DoubleLinkedQueue() {
102 _sentinel = new _DoubleLinkedQueueEntrySentinel<E>();
103 }
104
105 factory DoubleLinkedQueue.from(Iterable<E> other) {
106 Queue<E> list = new DoubleLinkedQueue();
107 for (final e in other) {
108 list.addLast(e);
109 }
110 return list;
111 }
112
113 void addLast(E value) {
114 _sentinel.prepend(value);
115 }
116
117 void addFirst(E value) {
118 _sentinel.append(value);
119 }
120
121 void add(E value) {
122 addLast(value);
123 }
124
125 void addAll(Collection<E> collection) {
126 for (final e in collection) {
127 add(e);
128 }
129 }
130
131 E removeLast() {
132 return _sentinel._previous.remove();
133 }
134
135 E removeFirst() {
136 return _sentinel._next.remove();
137 }
138
139 E first() {
140 return _sentinel._next.element;
141 }
142
143 E last() {
144 return _sentinel._previous.element;
145 }
146
147 DoubleLinkedQueueEntry<E> lastEntry() {
148 return _sentinel.previousEntry();
149 }
150
151 DoubleLinkedQueueEntry<E> firstEntry() {
152 return _sentinel.nextEntry();
153 }
154
155 int get length() {
156 int counter = 0;
157 forEach(void _(E element) { counter++; });
158 return counter;
159 }
160
161 bool isEmpty() {
162 return (_sentinel._next === _sentinel);
163 }
164
165 void clear() {
166 _sentinel._next = _sentinel;
167 _sentinel._previous = _sentinel;
168 }
169
170 void forEach(void f(E element)) {
171 DoubleLinkedQueueEntry<E> entry = _sentinel._next;
172 while (entry !== _sentinel) {
173 DoubleLinkedQueueEntry<E> nextEntry = entry._next;
174 f(entry._element);
175 entry = nextEntry;
176 }
177 }
178
179 void forEachEntry(void f(DoubleLinkedQueueEntry<E> element)) {
180 DoubleLinkedQueueEntry<E> entry = _sentinel._next;
181 while (entry !== _sentinel) {
182 DoubleLinkedQueueEntry<E> nextEntry = entry._next;
183 f(entry);
184 entry = nextEntry;
185 }
186 }
187
188 bool every(bool f(E element)) {
189 DoubleLinkedQueueEntry<E> entry = _sentinel._next;
190 while (entry !== _sentinel) {
191 DoubleLinkedQueueEntry<E> nextEntry = entry._next;
192 if (!f(entry._element)) return false;
193 entry = nextEntry;
194 }
195 return true;
196 }
197
198 bool some(bool f(E element)) {
199 DoubleLinkedQueueEntry<E> entry = _sentinel._next;
200 while (entry !== _sentinel) {
201 DoubleLinkedQueueEntry<E> nextEntry = entry._next;
202 if (f(entry._element)) return true;
203 entry = nextEntry;
204 }
205 return false;
206 }
207
208 Queue map(f(E element)) {
209 Queue other = new Queue();
210 DoubleLinkedQueueEntry<E> entry = _sentinel._next;
211 while (entry !== _sentinel) {
212 DoubleLinkedQueueEntry<E> nextEntry = entry._next;
213 other.addLast(f(entry._element));
214 entry = nextEntry;
215 }
216 return other;
217 }
218
219 Dynamic reduce(Dynamic initialValue,
220 Dynamic combine(Dynamic previousValue, E element)) {
221 return Collections.reduce(this, initialValue, combine);
222 }
223
224 Queue<E> filter(bool f(E element)) {
225 Queue<E> other = new Queue<E>();
226 DoubleLinkedQueueEntry<E> entry = _sentinel._next;
227 while (entry !== _sentinel) {
228 DoubleLinkedQueueEntry<E> nextEntry = entry._next;
229 if (f(entry._element)) other.addLast(entry._element);
230 entry = nextEntry;
231 }
232 return other;
233 }
234
235 _DoubleLinkedQueueIterator<E> iterator() {
236 return new _DoubleLinkedQueueIterator<E>(_sentinel);
237 }
238
239 String toString() {
240 return Collections.collectionToString(this);
241 }
242 }
243
244 class _DoubleLinkedQueueIterator<E> implements Iterator<E> {
245 final _DoubleLinkedQueueEntrySentinel<E> _sentinel;
246 DoubleLinkedQueueEntry<E> _currentEntry;
247
248 _DoubleLinkedQueueIterator(_DoubleLinkedQueueEntrySentinel this._sentinel) {
249 _currentEntry = _sentinel;
250 }
251
252 bool hasNext() {
253 return _currentEntry._next !== _sentinel;
254 }
255
256 E next() {
257 if (!hasNext()) {
258 throw const NoMoreElementsException();
259 }
260 _currentEntry = _currentEntry._next;
261 return _currentEntry.element;
262 }
263 }
OLDNEW
« no previous file with comments | « corelib/src/implementation/print.dart ('k') | corelib/src/implementation/regexp.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698