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

Side by Side Diff: pkg/compiler/lib/src/util/enumset.dart

Issue 1568213003: Add EnumSet. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 4 years, 11 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
« no previous file with comments | « pkg/compiler/lib/src/universe/class_set.dart ('k') | pkg/compiler/lib/src/world.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) 2016, 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 library dart2js.util.enumset;
6
7 import 'dart:collection';
8
9 /// A set of enum values based on a bit mask of the shifted enum indices.
10 abstract class EnumSet<E> {
11 /// Creates an empty mutable set.
12 factory EnumSet() = _EnumSet<E>;
13
14 /// Creates a mutable set from the bit mask [value].
15 factory EnumSet.fromValue(int value) = _EnumSet<E>.fromValue;
16
17 /// Creates an immutable set from the bit mask [value].
18 const factory EnumSet.fixed(int value) = _ConstEnumSet<E>;
19
20 /// Create a set containing the [values]. If [fixed] is `true` the set is
21 /// immutable.
22 factory EnumSet.fromValues(Iterable<E> values, {bool fixed: false}) {
23 if (fixed) {
24 return new _ConstEnumSet<E>.fromValues(values);
25 } else {
26 return new _EnumSet<E>.fromValues(values);
27 }
28 }
29
30 const EnumSet._();
31
32 /// The bit mask of the shifted indices for the enum values in this set.
33 int get value;
34
35 /// Adds [enumValue] to this set.
36 void add(E enumValue);
37
38 /// Removes [enumValue] from this set.
39 void remove(E enumValue);
40
41 /// Clears this set.
42 void clear();
43
44 /// Returns `true` if [enumValue] is in this set.
45 bool contains(E enumValue) {
46 return (value & (1 << (enumValue as dynamic).index)) != 0;
47 }
48
49 /// Returns an [Iterable] of the values is in this set using [values] to
50 /// convert the stored indices to enum values.
51 ///
52 /// The method is typically called with the `values` property of the enum
53 /// class as argument:
54 ///
55 /// EnumSet<EnumClass> set = ...
56 /// Iterable<EnumClass> iterable = set.iterable(EnumClass.values);
57 ///
58 Iterable<E> iterable(List<E> values) {
59 return new _EnumSetIterable(this, values);
60 }
61
62 /// Returns `true` if this and [other] have any elements in common.
63 bool intersects(EnumSet<E> other) {
64 return (value & other.value) != 0;
65 }
66
67 /// Returns `true` if this set is empty.
68 bool get isEmpty => value == 0;
69
70 int get hashCode => value.hashCode * 19;
71
72 bool operator ==(other) {
73 if (identical(this, other)) return true;
74 if (other is! EnumSet<E>) return false;
75 return value == other.value;
76 }
77
78 String toString() {
79 if (value == 0) return '0';
80 int index = value.bitLength - 1;
81 StringBuffer sb = new StringBuffer();
82 int mask = 1 << index;
83 while (index >= 0) {
84 sb.write((value & mask) != 0 ? '1' : '0');
85 index--;
86 mask >>= 1;
87 }
88 return sb.toString();
89 }
90 }
91
92 /// Mutable implementation of [EnumSet].
93 class _EnumSet<E> extends EnumSet<E> {
94 int _value;
95
96 _EnumSet() : this.fromValue(0);
97
98 _EnumSet.fromValue(this._value) : super._();
99
100 _EnumSet.fromValues(Iterable<E> values)
101 : this._value = 0,
102 super._() {
103 values.forEach(add);
104 }
105
106 int get value => _value;
107
108 void add(E enumValue) {
109 _value |= 1 << (enumValue as dynamic).index;
110 }
111
112 void remove(E enumValue) {
113 _value &= ~(1 << (enumValue as dynamic).index);
114 }
115
116 void clear() {
117 _value = 0;
118 }
119 }
120
121 /// Immutable implementation of [EnumSet].
122 class _ConstEnumSet<E> extends EnumSet<E> {
123 final int value;
124
125 const _ConstEnumSet(this.value) : super._();
126
127 factory _ConstEnumSet.fromValues(Iterable<E> values) {
128 int value = 0;
129 void add(E enumValue) {
130 if (enumValue != null) {
131 value |= 1 << (enumValue as dynamic).index;
132 }
133 }
134 values.forEach(add);
135 return new _ConstEnumSet(value);
136 }
137
138 @override
139 void add(E enumValue) {
140 throw new UnsupportedError('EnumSet.add');
141 }
142
143 @override
144 void clear() {
145 throw new UnsupportedError('EnumSet.clear');
146 }
147
148 @override
149 void remove(E enumValue) {
150 throw new UnsupportedError('EnumSet.remove');
151 }
152 }
153
154 class _EnumSetIterable<E> extends IterableBase<E> {
155 final EnumSet<E> _enumSet;
156 final List<E> _values;
157
158 _EnumSetIterable(this._enumSet, this._values);
159
160 @override
161 Iterator<E> get iterator => new _EnumSetIterator(_enumSet.value, _values);
162 }
163
164 class _EnumSetIterator<E> implements Iterator<E> {
165 int _value;
166 int _index;
167 int _mask;
168 final List<E> _values;
169 E _current;
170
171 _EnumSetIterator(this._value, this._values);
172
173 @override
174 E get current => _current;
175
176 @override
177 bool moveNext() {
178 if (_value == 0) {
179 return false;
180 } else {
181 if (_mask == null) {
182 _index = _value.bitLength - 1;
183 _mask = 1 << _index;
184 }
185 _current = null;
186 while (_index >= 0) {
187 if (_mask & _value != 0) {
188 _current = _values[_index];
189 }
190 _mask >>= 1;
191 _index--;
192 if (_current != null) {
193 break;
194 }
195 }
196 return _current != null;
197 }
198 }
199 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/universe/class_set.dart ('k') | pkg/compiler/lib/src/world.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698