diff options
author | Joe Tsai <joetsai@digital-static.net> | 2017-08-02 16:32:40 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-02 16:32:40 -0700 |
commit | 3fe02156777c9eff14a88826cf3aa495b5db3544 (patch) | |
tree | 5ce399040f003cb90006678f98f9201d211ec56e /cmp/internal | |
parent | 48a041be5648cc13e0c53082193ed105a0aa99e6 (diff) | |
download | go-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.go | 49 |
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 +} |