Skip to content

Commit

Permalink
slices,maps: delegate to go1.21 functions of the same name
Browse files Browse the repository at this point in the history
This change replaces the body of almost every function in the package
with a call to its corresponding std function of the same name
and--assumedly--semantics.

If proposal golang/go#32816 is accepted, we will annotate each function
with a "//go:fix inline" comment so that automated tooling
such as golang.org/x/tools/internal/refactor/inline/analyzer
can automatically inline the wrappers.

(This CL is deemed to fix golang/go#70717 because it reduces maps.Clear
to the same status as all the other maps functions.)

Updates golang/go#32816
Updates golang/go#70815
Fixes   golang/go#70717

Change-Id: I85246df07f903af97673b80024acdcae057b9f63
Reviewed-on: https://go-review.googlesource.com/c/exp/+/635680
Auto-Submit: Alan Donovan <adonovan@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
  • Loading branch information
adonovan authored and gopherbot committed Dec 15, 2024
1 parent 1829a12 commit 4a55095
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 1,577 deletions.
2 changes: 2 additions & 0 deletions constraints/constraints.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ type Complex interface {
// that supports the operators < <= >= >.
// If future releases of Go add new ordered types,
// this constraint will be modified to include them.
//
// This type is redundant since Go 1.21 introduced [cmp.Ordered].
type Ordered interface {
Integer | Float | ~string
}
58 changes: 20 additions & 38 deletions maps/maps.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,20 @@
// Package maps defines various functions useful with maps of any type.
package maps

import "maps"

// TODO(adonovan): when https://go.dev/issue/32816 is accepted, all of
// these functions except Keys and Values should be annotated
// (provisionally with "//go:fix inline") so that tools can safely and
// automatically replace calls to exp/maps with calls to std maps by
// inlining them.

// Keys returns the keys of the map m.
// The keys will be in an indeterminate order.
func Keys[M ~map[K]V, K comparable, V any](m M) []K {
// The simplest true equivalent using std is:
// return slices.AppendSeq(make([]K, 0, len(m)), maps.Keys(m)).

r := make([]K, 0, len(m))
for k := range m {
r = append(r, k)
Expand All @@ -18,6 +29,9 @@ func Keys[M ~map[K]V, K comparable, V any](m M) []K {
// Values returns the values of the map m.
// The values will be in an indeterminate order.
func Values[M ~map[K]V, K comparable, V any](m M) []V {
// The simplest true equivalent using std is:
// return slices.AppendSeq(make([]V, 0, len(m)), maps.Values(m)).

r := make([]V, 0, len(m))
for _, v := range m {
r = append(r, v)
Expand All @@ -28,67 +42,35 @@ func Values[M ~map[K]V, K comparable, V any](m M) []V {
// Equal reports whether two maps contain the same key/value pairs.
// Values are compared using ==.
func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool {
if len(m1) != len(m2) {
return false
}
for k, v1 := range m1 {
if v2, ok := m2[k]; !ok || v1 != v2 {
return false
}
}
return true
return maps.Equal(m1, m2)
}

// EqualFunc is like Equal, but compares values using eq.
// Keys are still compared with ==.
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 {
if len(m1) != len(m2) {
return false
}
for k, v1 := range m1 {
if v2, ok := m2[k]; !ok || !eq(v1, v2) {
return false
}
}
return true
return maps.EqualFunc(m1, m2, eq)
}

// Clear removes all entries from m, leaving it empty.
func Clear[M ~map[K]V, K comparable, V any](m M) {
for k := range m {
delete(m, k)
}
clear(m)
}

// Clone returns a copy of m. This is a shallow clone:
// the new keys and values are set using ordinary assignment.
func Clone[M ~map[K]V, K comparable, V any](m M) M {
// Preserve nil in case it matters.
if m == nil {
return nil
}
r := make(M, len(m))
for k, v := range m {
r[k] = v
}
return r
return maps.Clone(m)
}

// Copy copies all key/value pairs in src adding them to dst.
// When a key in src is already present in dst,
// the value in dst will be overwritten by the value associated
// with the key in src.
func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) {
for k, v := range src {
dst[k] = v
}
maps.Copy(dst, src)
}

// DeleteFunc deletes any key/value pairs from m for which del returns true.
func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) {
for k, v := range m {
if del(k, v) {
delete(m, k)
}
}
maps.DeleteFunc(m, del)
}
44 changes: 0 additions & 44 deletions slices/cmp.go

This file was deleted.

Loading

0 comments on commit 4a55095

Please sign in to comment.