1 // Copyright 2021 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 5 // Package maps defines various functions useful with maps of any type.
6 //
7 // This package does not have any special handling for non-reflexive keys
8 // (keys k where k != k), such as floating-point NaNs.
9 package maps
10 11 import (
12 _ "unsafe"
13 )
14 15 // Equal reports whether two maps contain the same key/value pairs.
16 // Values are compared using ==.
17 func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool {
18 if len(m1) != len(m2) {
19 return false
20 }
21 for k, v1 := range m1 {
22 if v2, ok := m2[k]; !ok || v1 != v2 {
23 return false
24 }
25 }
26 return true
27 }
28 29 // EqualFunc is like Equal, but compares values using eq.
30 // Keys are still compared with ==.
31 func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool {
32 if len(m1) != len(m2) {
33 return false
34 }
35 for k, v1 := range m1 {
36 if v2, ok := m2[k]; !ok || !eq(v1, v2) {
37 return false
38 }
39 }
40 return true
41 }
42 43 // clone is implemented in the runtime package.
44 //
45 //go:linkname clone maps.clone
46 func clone(m any) any
47 48 // Clone returns a copy of m. This is a shallow clone:
49 // the new keys and values are set using ordinary assignment.
50 func Clone[M ~map[K]V, K comparable, V any](m M) M {
51 // Preserve nil in case it matters.
52 if m == nil {
53 return nil
54 }
55 return clone(m).(M)
56 }
57 58 // Copy copies all key/value pairs in src adding them to dst.
59 // When a key in src is already present in dst,
60 // the value in dst will be overwritten by the value associated
61 // with the key in src.
62 func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) {
63 for k, v := range src {
64 dst[k] = v
65 }
66 }
67 68 // DeleteFunc deletes any key/value pairs from m for which del returns true.
69 func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) {
70 for k, v := range m {
71 if del(k, v) {
72 delete(m, k)
73 }
74 }
75 }
76