blob: c77a072f96028656a8a946ed1ef0f9481a5de18f [file] [log] [blame]
class Tuple<T1, T2> {
final T1 item1;
final T2 item2;
const Tuple(this.item1, this.item2);
@override
bool operator ==(other) {
return other is Tuple && item1 == other.item1 && item2 == other.item2;
}
@override
String toString() => '{item1: $item1, item2: $item2}';
@override
int get hashCode => Util.getHashCode([item1, item2]);
dynamic toJson() => {'item1': item1, 'item2': item2};
}
class Util {
static int getHashCode(Iterable source) {
requireArgumentNotNull(source, 'source');
int hash = 0;
for (final h in source) {
int next = h == null ? 0 : h.hashCode;
hash = 0x1fffffff & (hash + next);
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
hash ^= hash >> 6;
}
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
hash ^= hash >> 11;
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
}
}
void require(bool truth, [String message]) {
if (!truth) {
throw new Exception(message);
}
}
void requireArgumentNotNull(argument, String argName) {
_metaRequireArgumentNotNullOrEmpty(argName);
if (argument == null) {
throw new ArgumentError.notNull(argName);
}
}
void _metaRequireArgumentNotNullOrEmpty(String argName) {
if (argName == null || argName.isEmpty) {
throw new UnsupportedError("That's just sad. Give me a good argName");
}
}