aboutsummaryrefslogtreecommitdiff
path: root/cmp/internal
diff options
context:
space:
mode:
authorJoe Tsai <joetsai@digital-static.net>2017-08-02 16:32:40 -0700
committerGitHub <noreply@github.com>2017-08-02 16:32:40 -0700
commit3fe02156777c9eff14a88826cf3aa495b5db3544 (patch)
tree5ce399040f003cb90006678f98f9201d211ec56e /cmp/internal
parent48a041be5648cc13e0c53082193ed105a0aa99e6 (diff)
downloadgo-cmp-3fe02156777c9eff14a88826cf3aa495b5db3544.tar.gz
Add cmp/internal/function package (#35)
Unify the common logic for identifying the type of function. This logic is helpful since Go lacks generics, so it is hard to query whether a function is of the signature: func(T, T) bool
Diffstat (limited to 'cmp/internal')
-rw-r--r--cmp/internal/function/func.go49
1 files changed, 49 insertions, 0 deletions
diff --git a/cmp/internal/function/func.go b/cmp/internal/function/func.go
new file mode 100644
index 0000000..4c35ff1
--- /dev/null
+++ b/cmp/internal/function/func.go
@@ -0,0 +1,49 @@
+// Copyright 2017, The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE.md file.
+
+// Package function identifies function types.
+package function
+
+import "reflect"
+
+type funcType int
+
+const (
+ _ funcType = iota
+
+ ttbFunc // func(T, T) bool
+ tibFunc // func(T, I) bool
+ trFunc // func(T) R
+
+ Equal = ttbFunc // func(T, T) bool
+ EqualAssignable = tibFunc // func(T, I) bool; encapsulates func(T, T) bool
+ Transformer = trFunc // func(T) R
+ ValueFilter = ttbFunc // func(T, T) bool
+ Less = ttbFunc // func(T, T) bool
+)
+
+var boolType = reflect.TypeOf(true)
+
+// IsType reports whether the reflect.Type is of the specified function type.
+func IsType(t reflect.Type, ft funcType) bool {
+ if t == nil || t.Kind() != reflect.Func || t.IsVariadic() {
+ return false
+ }
+ ni, no := t.NumIn(), t.NumOut()
+ switch ft {
+ case ttbFunc: // func(T, T) bool
+ if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType {
+ return true
+ }
+ case tibFunc: // func(T, I) bool
+ if ni == 2 && no == 1 && t.In(0).AssignableTo(t.In(1)) && t.Out(0) == boolType {
+ return true
+ }
+ case trFunc: // func(T) R
+ if ni == 1 && no == 1 {
+ return true
+ }
+ }
+ return false
+}