// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. // Immutable map class for compiler generated map literals. class ImmutableMap implements Map { final _ImmutableArray kvPairs_; const ImmutableMap._create(_ImmutableArray keyValuePairs) : kvPairs_ = keyValuePairs; V operator [](K key) { // TODO(hausner): Since the keys are sorted, we could do a binary // search. But is it worth it? for (int i = 0; i < kvPairs_.length - 1; i += 2) { if (key == kvPairs_[i]) { return kvPairs_[i+1]; } } return null; } bool get isEmpty { return kvPairs_.length == 0; } int get length { return kvPairs_.length ~/ 2; } void forEach(void f(K key, V value)) { for (int i = 0; i < kvPairs_.length; i += 2) { f(kvPairs_[i], kvPairs_[i+1]); } } Iterable get keys { return new _ImmutableMapKeyIterable(this); } Iterable get values { return new _ImmutableMapValueIterable(this); } bool containsKey(K key) { for (int i = 0; i < kvPairs_.length; i += 2) { if (key == kvPairs_[i]) { return true; } } return false; } bool containsValue(V value) { for (int i = 1; i < kvPairs_.length; i += 2) { if (value == kvPairs_[i]) { return true; } } return false; } void operator []=(K key, V value) { throw new UnsupportedError("Cannot set value in unmodifiable Map"); } V putIfAbsent(K key, V ifAbsent()) { throw new UnsupportedError("Cannot set value in unmodifiable Map"); } void clear() { throw new UnsupportedError("Cannot clear unmodifiable Map"); } V remove(K key) { throw new UnsupportedError("Cannot remove from unmodifiable Map"); } String toString() { return Maps.mapToString(this); } } class _ImmutableMapKeyIterable extends Iterable { final ImmutableMap _map; _ImmutableMapKeyIterable(this._map); Iterator get iterator { return new _ImmutableMapKeyIterator(_map); } } class _ImmutableMapValueIterable extends Iterable { final ImmutableMap _map; _ImmutableMapValueIterable(this._map); Iterator get iterator { return new _ImmutableMapValueIterator(_map); } } class _ImmutableMapKeyIterator implements Iterator { ImmutableMap _map; int _index = -1; E _current; _ImmutableMapKeyIterator(this._map); bool moveNext() { int newIndex = _index + 1; if (newIndex < _map.length) { _index = newIndex; _current = _map.kvPairs_[newIndex * 2]; return true; } _current = null; _index = _map.length; return false; } E get current => _current; } class _ImmutableMapValueIterator implements Iterator { ImmutableMap _map; int _index = -1; E _current; _ImmutableMapValueIterator(this._map); bool moveNext() { int newIndex = _index + 1; if (newIndex < _map.length) { _index = newIndex; _current = _map.kvPairs_[newIndex * 2 + 1]; return true; } _current = null; _index = _map.length; return false; } E get current => _current; }