mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 15:01:30 +00:00
df97aca1fa
Closes https://github.com/dart-lang/sdk/pull/50764 GitOrigin-RevId: ee2fe9a75d50e877f4ad2fe3743acdbc04f186ef Change-Id: Ia73cd22da4e6ec95e84772aa4e1345ce2dbde215 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/276360 Reviewed-by: Erik Ernst <eernst@google.com> Commit-Queue: Erik Ernst <eernst@google.com>
136 lines
3.6 KiB
Dart
136 lines
3.6 KiB
Dart
// Copyright (c) 2018, 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.
|
|
|
|
// @dart=2.9
|
|
|
|
import "dart:math";
|
|
import "dart:typed_data";
|
|
|
|
import "package:expect/expect.dart";
|
|
|
|
main() {
|
|
const nan = double.nan;
|
|
const inf = double.infinity;
|
|
|
|
int hash1234 = Object.hash(1, 2, 3, 4);
|
|
Expect.type<int>(hash1234);
|
|
Expect.equals(hash1234, Object.hash(1, 2, 3, 4)); // Consistent.
|
|
Expect.equals(hash1234, Object.hashAll([1, 2, 3, 4]));
|
|
Expect.equals(hash1234, Object.hashAll(Uint8List.fromList([1, 2, 3, 4])));
|
|
|
|
Expect.notEquals(hash1234, Object.hash(1, 2, 3, 4, null));
|
|
|
|
Expect.equals(Object.hash(1, 2, 3, 4, 5, 6, 7, 8, 9),
|
|
Object.hashAll([1, 2, 3, 4, 5, 6, 7, 8, 9]));
|
|
|
|
// Check that we can call `hash` with 2-20 arguments,
|
|
// and they all agree with `hashAll`.
|
|
var random = Random();
|
|
for (var i = 2; i <= 20; i++) {
|
|
var arguments = [for (var j = 0; j < i; j++) random.nextInt(256)];
|
|
var hashAll = Object.hashAll(arguments);
|
|
var hash = Function.apply(Object.hash, arguments);
|
|
Expect.equals(
|
|
hashAll,
|
|
hash,
|
|
"hashAll and hash disagrees for $i values:\n"
|
|
"$arguments");
|
|
}
|
|
|
|
// Works for all kinds of objects;
|
|
int varHash = Object.hash(
|
|
"string", 3, nan, true, null, Type, #Symbol, const Object(), function);
|
|
Expect.equals(
|
|
varHash,
|
|
Object.hashAll([
|
|
"string",
|
|
3,
|
|
nan,
|
|
true,
|
|
null,
|
|
Type,
|
|
#Symbol,
|
|
const Object(),
|
|
function
|
|
]));
|
|
|
|
// Object doesn't matter, just its hash code.
|
|
Expect.equals(hash1234,
|
|
Object.hash(Hashable(1), Hashable(2), Hashable(3), Hashable(4)));
|
|
|
|
// It's potentially possible to get a conflict, but it doesn't happen here.
|
|
Expect.notEquals("str".hashCode, Object.hashAll(["str"]));
|
|
|
|
var hash12345 = Object.hashAllUnordered([1, 2, 3, 4, 5]);
|
|
for (var p in permutations([1, 2, 3, 4, 5])) {
|
|
Expect.equals(hash12345, Object.hashAllUnordered(p));
|
|
}
|
|
Expect.notEquals(
|
|
Object.hashAllUnordered(["a", "a"]), Object.hashAllUnordered(["a"]));
|
|
|
|
Expect.notEquals(Object.hashAllUnordered(["a", "a"]),
|
|
Object.hashAllUnordered(["a", "a", "a", "a"]));
|
|
|
|
Expect.notEquals(Object.hashAllUnordered(["a", "b"]),
|
|
Object.hashAllUnordered(["a", "a", "a", "b"]));
|
|
|
|
/// Unordered hashing works for all kinds of objects.
|
|
var unorderHash = Object.hashAllUnordered([
|
|
"string",
|
|
3,
|
|
nan,
|
|
true,
|
|
null,
|
|
Type,
|
|
#Symbol,
|
|
const Object(),
|
|
function,
|
|
]);
|
|
|
|
var unorderHash2 = Object.hashAllUnordered([
|
|
true,
|
|
const Object(),
|
|
3,
|
|
function,
|
|
Type,
|
|
"string",
|
|
null,
|
|
nan,
|
|
#Symbol,
|
|
]);
|
|
Expect.equals(unorderHash, unorderHash2);
|
|
}
|
|
|
|
/// Lazily emits all permutations of [values].
|
|
///
|
|
/// Modifies [values] rather than create a new list.
|
|
/// The [values] list is guaranteed to end up in its original state
|
|
/// after all permutations have been read.
|
|
Iterable<List<T>> permutations<T>(List<T> values) {
|
|
Iterable<List<T>> recPermute(int end) sync* {
|
|
if (end == 1) {
|
|
yield values;
|
|
return;
|
|
}
|
|
for (var i = 0; i < end; i++) {
|
|
yield* recPermute(end - 1);
|
|
// Rotate values[i:].
|
|
var tmp = values.first;
|
|
for (var k = 1; k < end; k++) values[k - 1] = values[k];
|
|
values[end - 1] = tmp;
|
|
}
|
|
}
|
|
|
|
return recPermute(values.length);
|
|
}
|
|
|
|
// static function, used as constant value.
|
|
void function() {}
|
|
|
|
class Hashable {
|
|
final Object o;
|
|
Hashable(this.o);
|
|
bool operator ==(Object other) => other is Hashable && o == other.o;
|
|
int get hashCode => o.hashCode;
|
|
}
|