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 part of dart2js.util; |
| 6 |
| 7 class Link<T> implements Iterable<T> { |
| 8 T get head => throw new StateError("no elements"); |
| 9 Link<T> get tail => null; |
| 10 |
| 11 const Link(); |
| 12 |
| 13 Link<T> prepend(T element) { |
| 14 return new LinkEntry<T>(element, this); |
| 15 } |
| 16 |
| 17 Iterator<T> get iterator => new LinkIterator<T>(this); |
| 18 |
| 19 void printOn(StringBuffer buffer, [separatedBy]) {} |
| 20 |
| 21 List<T> toList({bool growable: true}) { |
| 22 List<T> result; |
| 23 if (!growable) { |
| 24 result = new List<T>(slowLength()); |
| 25 } else { |
| 26 result = new List<T>(); |
| 27 result.length = slowLength(); |
| 28 } |
| 29 int i = 0; |
| 30 for (Link<T> link = this; !link.isEmpty; link = link.tail) { |
| 31 result[i++] = link.head; |
| 32 } |
| 33 return result; |
| 34 } |
| 35 |
| 36 /// Lazily maps over this linked list, returning an [Iterable]. |
| 37 Iterable map(dynamic fn(T item)) { |
| 38 return new MappedLinkIterable<T, dynamic>(this, fn); |
| 39 } |
| 40 |
| 41 /// Invokes `fn` for every item in the linked list and returns the results |
| 42 /// in a [List]. |
| 43 List mapToList(dynamic fn(T item), {bool growable: true}) { |
| 44 List result; |
| 45 if (!growable) { |
| 46 result = new List(slowLength()); |
| 47 } else { |
| 48 result = new List(); |
| 49 result.length = slowLength(); |
| 50 } |
| 51 int i = 0; |
| 52 for (Link<T> link = this; !link.isEmpty; link = link.tail) { |
| 53 result[i++] = fn(link.head); |
| 54 } |
| 55 return result; |
| 56 } |
| 57 |
| 58 bool get isEmpty => true; |
| 59 bool get isNotEmpty => false; |
| 60 |
| 61 Link<T> reverse() => this; |
| 62 |
| 63 Link<T> reversePrependAll(Link<T> from) { |
| 64 if (from.isEmpty) return this; |
| 65 return this.prepend(from.head).reversePrependAll(from.tail); |
| 66 } |
| 67 |
| 68 Link<T> skip(int n) { |
| 69 if (n == 0) return this; |
| 70 throw new RangeError('Index $n out of range'); |
| 71 } |
| 72 |
| 73 void forEach(void f(T element)) {} |
| 74 |
| 75 bool operator ==(other) { |
| 76 if (other is! Link<T>) return false; |
| 77 return other.isEmpty; |
| 78 } |
| 79 |
| 80 int get hashCode => throw new UnsupportedError('Link.hashCode'); |
| 81 |
| 82 String toString() => "[]"; |
| 83 |
| 84 get length { |
| 85 throw new UnsupportedError('get:length'); |
| 86 } |
| 87 |
| 88 int slowLength() => 0; |
| 89 |
| 90 // TODO(ahe): Remove this method? |
| 91 bool contains(T element) { |
| 92 for (Link<T> link = this; !link.isEmpty; link = link.tail) { |
| 93 if (link.head == element) return true; |
| 94 } |
| 95 return false; |
| 96 } |
| 97 |
| 98 // TODO(ahe): Remove this method? |
| 99 T get single { |
| 100 if (isEmpty) throw new StateError('No elements'); |
| 101 if (!tail.isEmpty) throw new StateError('More than one element'); |
| 102 return head; |
| 103 } |
| 104 |
| 105 // TODO(ahe): Remove this method? |
| 106 T get first { |
| 107 if (isEmpty) throw new StateError('No elements'); |
| 108 return head; |
| 109 } |
| 110 |
| 111 /// Returns true if f returns true for all elements of this list. |
| 112 /// |
| 113 /// Returns true for the empty list. |
| 114 bool every(bool f(T)) { |
| 115 for (Link<T> link = this; !link.isEmpty; link = link.tail) { |
| 116 if (!f(link.head)) return false; |
| 117 } |
| 118 return true; |
| 119 } |
| 120 |
| 121 Link copyWithout(e) => this; |
| 122 |
| 123 // |
| 124 // Unsupported Iterable<T> methods. |
| 125 // |
| 126 bool any(bool f(T e)) => _unsupported('any'); |
| 127 T elementAt(int i) => _unsupported('elementAt'); |
| 128 Iterable expand(Iterable f(T e)) => _unsupported('expand'); |
| 129 T firstWhere(bool f(T e), {T orElse()}) => _unsupported('firstWhere'); |
| 130 fold(initialValue, combine(value, T element)) => _unsupported('fold'); |
| 131 T get last => _unsupported('get:last'); |
| 132 T lastWhere(bool f(T e), {T orElse()}) => _unsupported('lastWhere'); |
| 133 String join([separator = '']) => _unsupported('join'); |
| 134 T reduce(T combine(T a, T b)) => _unsupported('reduce'); |
| 135 T singleWhere(bool f(T e)) => _unsupported('singleWhere'); |
| 136 Iterable<T> skipWhile(bool f(T e)) => _unsupported('skipWhile'); |
| 137 Iterable<T> take(int n) => _unsupported('take'); |
| 138 Iterable<T> takeWhile(bool f(T e)) => _unsupported('takeWhile'); |
| 139 Set<T> toSet() => _unsupported('toSet'); |
| 140 Iterable<T> where(bool f(T e)) => _unsupported('where'); |
| 141 |
| 142 _unsupported(String method) => throw new UnsupportedError(method); |
| 143 } |
| 144 |
| 145 /// Builder object for creating linked lists using [Link] or fixed-length [List] |
| 146 /// objects. |
| 147 abstract class LinkBuilder<T> { |
| 148 factory LinkBuilder() = LinkBuilderImplementation; |
| 149 |
| 150 /// Prepends all elements added to the builder to [tail]. The resulting list |
| 151 /// is returned and the builder is cleared. |
| 152 Link<T> toLink([Link<T> tail = const Link()]); |
| 153 |
| 154 /// Creates a new fixed length containing all added elements. The |
| 155 /// resulting list is returned and the builder is cleared. |
| 156 List<T> toList(); |
| 157 |
| 158 /// Adds the element [t] to the end of the list being built. |
| 159 Link<T> addLast(T t); |
| 160 |
| 161 /// Returns the first element in the list being built. |
| 162 T get first; |
| 163 |
| 164 /// Returns the number of elements in the list being built. |
| 165 final int length; |
| 166 |
| 167 /// Returns `true` if the list being built is empty. |
| 168 final bool isEmpty; |
| 169 |
| 170 /// Removes all added elements and resets the builder. |
| 171 void clear(); |
| 172 } |
OLD | NEW |