github.com/lovishpuri/go-40569/src@v0.0.0-20230519171745-f8623e7c56cf/maps/maps.go (about)

     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  package maps
     7  
     8  import "unsafe"
     9  
    10  // keys is implemented in the runtime package.
    11  //
    12  //go:noescape
    13  func keys(m any, slice unsafe.Pointer)
    14  
    15  // Keys returns the keys of the map m.
    16  // The keys will be in an indeterminate order.
    17  func Keys[M ~map[K]V, K comparable, V any](m M) []K {
    18  	r := make([]K, 0, len(m))
    19  	keys(m, unsafe.Pointer(&r))
    20  	return r
    21  }
    22  
    23  func keysForBenchmarking[M ~map[K]V, K comparable, V any](m M, s []K) {
    24  	keys(m, unsafe.Pointer(&s))
    25  }
    26  
    27  // Values returns the values of the map m.
    28  // The values will be in an indeterminate order.
    29  func Values[M ~map[K]V, K comparable, V any](m M) []V {
    30  	r := make([]V, 0, len(m))
    31  	for _, v := range m {
    32  		r = append(r, v)
    33  	}
    34  	return r
    35  }
    36  
    37  // Equal reports whether two maps contain the same key/value pairs.
    38  // Values are compared using ==.
    39  func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool {
    40  	if len(m1) != len(m2) {
    41  		return false
    42  	}
    43  	for k, v1 := range m1 {
    44  		if v2, ok := m2[k]; !ok || v1 != v2 {
    45  			return false
    46  		}
    47  	}
    48  	return true
    49  }
    50  
    51  // EqualFunc is like Equal, but compares values using eq.
    52  // Keys are still compared with ==.
    53  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 {
    54  	if len(m1) != len(m2) {
    55  		return false
    56  	}
    57  	for k, v1 := range m1 {
    58  		if v2, ok := m2[k]; !ok || !eq(v1, v2) {
    59  			return false
    60  		}
    61  	}
    62  	return true
    63  }
    64  
    65  // clone is implemented in the runtime package.
    66  func clone(m any) any
    67  
    68  // Clone returns a copy of m.  This is a shallow clone:
    69  // the new keys and values are set using ordinary assignment.
    70  func Clone[M ~map[K]V, K comparable, V any](m M) M {
    71  	// Preserve nil in case it matters.
    72  	if m == nil {
    73  		return nil
    74  	}
    75  	return clone(m).(M)
    76  }
    77  
    78  // Copy copies all key/value pairs in src adding them to dst.
    79  // When a key in src is already present in dst,
    80  // the value in dst will be overwritten by the value associated
    81  // with the key in src.
    82  func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) {
    83  	for k, v := range src {
    84  		dst[k] = v
    85  	}
    86  }
    87  
    88  // DeleteFunc deletes any key/value pairs from m for which del returns true.
    89  func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) {
    90  	for k, v := range m {
    91  		if del(k, v) {
    92  			delete(m, k)
    93  		}
    94  	}
    95  }