maps.mx raw

   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