private static long hash(this array x, types.Type t) { long h = 0L; ptr <types.Array> tElt = t.Underlying()._ <ptr <types.Array> >().Elem(); foreach (var(_, xi) in x) { h += hash(tElt, xi); } return(h); }
private static bool eq(this array x, types.Type t, object _y) { array y = _y._ <array>(); ptr <types.Array> tElt = t.Underlying()._ <ptr <types.Array> >().Elem(); foreach (var(i, xi) in x) { if (!equals(tElt, xi, y[i])) { return(false); } } return(true); }
private static long hash(this structure x, types.Type t) { ptr <types.Struct> tStruct = t.Underlying()._ <ptr <types.Struct> >(); long h = 0L; for (long i = 0L; var n = tStruct.NumFields(); i < n; i++) { { var f = tStruct.Field(i); if (!f.Anonymous()) { h += hash(f.Type(), x[i]); } } } return(h); }
// usesBuiltinMap returns true if the built-in hash function and // equivalence relation for type t are consistent with those of the // interpreter's representation of type t. Such types are: all basic // types (bool, numbers, string), pointers and channels. // // usesBuiltinMap returns false for types that require a custom map // implementation: interfaces, arrays and structs. // // Panic ensues if t is an invalid map key type: function, map or slice. private static bool usesBuiltinMap(types.Type t) => func((_, panic, __) => { switch (t.type()) { case ptr <types.Basic> t: return(true); break; case ptr <types.Chan> t: return(true); break; case ptr <types.Pointer> t: return(true); break; case ptr <types.Named> t: return(usesBuiltinMap(t.Underlying())); break; case ptr <types.Interface> t: return(false); break; case ptr <types.Array> t: return(false); break; case ptr <types.Struct> t: return(false); break; } panic(fmt.Sprintf("invalid map key type: %T", t)); });
private static bool eq(this structure x, types.Type t, object _y) { structure y = _y._ <structure>(); ptr <types.Struct> tStruct = t.Underlying()._ <ptr <types.Struct> >(); for (long i = 0L; var n = tStruct.NumFields(); i < n; i++) { { var f = tStruct.Field(i); if (!f.Anonymous()) { if (!equals(f.Type(), x[i], y[i])) { return(false); } } } } return(true); }