From 12f8c988230bbe33ba2a2a00d16540b0f9b9c605 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 7 Jun 2023 10:56:40 -0700 Subject: [PATCH] util/cmpx: add package with cmp-like things from future Go releases Updates #8296 Signed-off-by: Brad Fitzpatrick --- util/cmpx/cmpx.go | 22 ++++++++++++++++++++++ util/cmpx/cmpx_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 util/cmpx/cmpx.go create mode 100644 util/cmpx/cmpx_test.go diff --git a/util/cmpx/cmpx.go b/util/cmpx/cmpx.go new file mode 100644 index 000000000..d747f0a1d --- /dev/null +++ b/util/cmpx/cmpx.go @@ -0,0 +1,22 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package cmpx has code that will likely land in a future version of Go, but +// we want sooner. +package cmpx + +// Or returns the first non-zero element of list, or else returns the zero T. +// +// This is the proposal from +// https://github.com/golang/go/issues/60204#issuecomment-1581245334. +func Or[T comparable](list ...T) T { + // TODO(bradfitz): remove the comparable constraint so we can use this + // with funcs too and use reflect to see whether they're non-zero? 🤷‍♂️ + var zero T + for _, v := range list { + if v != zero { + return v + } + } + return zero +} diff --git a/util/cmpx/cmpx_test.go b/util/cmpx/cmpx_test.go new file mode 100644 index 000000000..768492dd7 --- /dev/null +++ b/util/cmpx/cmpx_test.go @@ -0,0 +1,24 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package cmpx + +import "testing" + +func TestOr(t *testing.T) { + if g, w := Or[string](), ""; g != w { + t.Errorf("got %v; want %v", g, w) + } + if g, w := Or[int](), 0; g != w { + t.Errorf("got %v; want %v", g, w) + } + if g, w := Or("", "foo", "bar"), "foo"; g != w { + t.Errorf("got %v; want %v", g, w) + } + if g, w := Or("foo", "bar"), "foo"; g != w { + t.Errorf("got %v; want %v", g, w) + } + if g, w := Or("", "", "bar"), "bar"; g != w { + t.Errorf("got %v; want %v", g, w) + } +}