OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011, 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 class LinkIterator<T> implements Iterator<T> { | |
6 Link<T> current; | |
7 LinkIterator(Link<T> this.current); | |
8 bool hasNext() => !current.isEmpty(); | |
9 T next() { | |
10 T result = current.head; | |
11 current = current.tail; | |
12 return result; | |
13 } | |
14 } | |
15 | |
16 class LinkFactory<T> { | |
17 factory Link(T head, [Link<T> tail]) { | |
18 if (tail === null) { | |
19 tail = new LinkTail<T>(); | |
20 } | |
21 return new LinkEntry<T>(head, tail); | |
22 } | |
23 | |
24 factory Link.fromList(List<T> list) { | |
25 switch (list.length) { | |
26 case 0: | |
27 return new LinkTail<T>(); | |
28 case 1: | |
29 return new Link<T>(list[0]); | |
30 case 2: | |
31 return new Link<T>(list[0], new Link<T>(list[1])); | |
32 case 3: | |
33 return new Link<T>(list[0], new Link<T>(list[1], new Link<T>(list[2]))); | |
34 } | |
35 Link link = new Link<T>(list.last()); | |
36 for (int i = list.length - 1; i > 0; i--) { | |
37 link = link.prepend(list[i - 1]); | |
38 } | |
39 return link; | |
40 } | |
41 } | |
42 | |
43 class LinkTail<T> implements EmptyLink<T> { | |
44 T get head() => null; | |
45 Link<T> get tail() => null; | |
46 | |
47 const LinkTail(); | |
48 | |
49 Link<T> prepend(T element) { | |
50 // TODO(ahe): Use new Link<T>, but this cost 8% performance on VM. | |
51 return new LinkEntry<T>(element, this); | |
52 } | |
53 | |
54 Iterator<T> iterator() => new LinkIterator<T>(this); | |
55 | |
56 void printOn(StringBuffer buffer, [separatedBy]) { | |
57 } | |
58 | |
59 String toString() => "[]"; | |
60 | |
61 Link<T> reverse() => this; | |
62 | |
63 Link<T> reversePrependAll(Link<T> from) { | |
64 if (from.isEmpty()) return this; | |
65 return from.head.reversePrependAll(from.tail); | |
66 } | |
67 | |
68 List toList() => const []; | |
69 | |
70 bool isEmpty() => true; | |
71 | |
72 void forEach(void f(T element)) {} | |
73 } | |
74 | |
75 class LinkEntry<T> implements Link<T> { | |
76 final T head; | |
77 Link<T> tail; | |
78 | |
79 LinkEntry(T this.head, Link<T> this.tail); | |
80 | |
81 Link<T> prepend(T element) { | |
82 // TODO(ahe): Use new Link<T>, but this cost 8% performance on VM. | |
83 return new LinkEntry<T>(element, this); | |
84 } | |
85 | |
86 Iterator<T> iterator() => new LinkIterator<T>(this); | |
87 | |
88 void printOn(StringBuffer buffer, [separatedBy]) { | |
89 buffer.add(head); | |
90 if (separatedBy === null) separatedBy = ''; | |
91 for (Link link = tail; !link.isEmpty(); link = link.tail) { | |
92 buffer.add(separatedBy); | |
93 buffer.add(link.head); | |
94 } | |
95 } | |
96 | |
97 String toString() { | |
98 StringBuffer buffer = new StringBuffer(); | |
99 buffer.add('[ '); | |
100 printOn(buffer, ', '); | |
101 buffer.add(' ]'); | |
102 return buffer.toString(); | |
103 } | |
104 | |
105 Link<T> reverse() { | |
106 Link<T> result = const LinkTail(); | |
107 for (Link<T> link = this; !link.isEmpty(); link = link.tail) { | |
108 result = result.prepend(link.head); | |
109 } | |
110 return result; | |
111 } | |
112 | |
113 Link<T> reversePrependAll(Link<T> from) { | |
114 Link<T> result; | |
115 for (result = this; !from.isEmpty(); from = from.tail) { | |
116 result = result.prepend(from.head); | |
117 } | |
118 return result; | |
119 } | |
120 | |
121 | |
122 bool isEmpty() => false; | |
123 | |
124 List<T> toList() { | |
125 List<T> list = new List<T>(); | |
126 for (Link<T> link = this; !link.isEmpty(); link = link.tail) { | |
127 list.addLast(link.head); | |
128 } | |
129 return list; | |
130 } | |
131 | |
132 void forEach(void f(T element)) { | |
133 for (Link<T> link = this; !link.isEmpty(); link = link.tail) { | |
134 f(link.head); | |
135 } | |
136 } | |
137 } | |
138 | |
139 class LinkBuilderImplementation<T> implements LinkBuilder<T> { | |
140 LinkEntry<T> head = null; | |
141 LinkEntry<T> lastLink = null; | |
142 int length = 0; | |
143 | |
144 LinkBuilderImplementation(); | |
145 | |
146 Link<T> toLink() { | |
147 if (head === null) return const LinkTail(); | |
148 lastLink.tail = const LinkTail(); | |
149 Link<T> link = head; | |
150 lastLink = null; | |
151 head = null; | |
152 return link; | |
153 } | |
154 | |
155 void addLast(T t) { | |
156 length++; | |
157 LinkEntry<T> entry = new LinkEntry<T>(t, null); | |
158 if (head === null) { | |
159 head = entry; | |
160 } else { | |
161 lastLink.tail = entry; | |
162 } | |
163 lastLink = entry; | |
164 } | |
165 } | |
OLD | NEW |