Skip to content

Commit

Permalink
add gnumerics and constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
miniLCT committed Apr 7, 2024
1 parent f4c4cbd commit e4eab32
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 0 deletions.
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
module github.com/miniLCT/gosb

go 1.22.0

require github.com/stretchr/testify v1.9.0

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
46 changes: 46 additions & 0 deletions gogenerics/constraints/constraints.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Package constraints `golang.org/x/exp/constraints` is experimental and unreliable,
// so remove it from the import path
package constraints

// Signed is a constraint that permits any signed integer type.
// If future releases of Go add new predeclared signed integer types,
// this constraint will be modified to include them.
type Signed interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}

// Unsigned is a constraint that permits any unsigned integer type.
// If future releases of Go add new predeclared unsigned integer types,
// this constraint will be modified to include them.
type Unsigned interface {
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}

// Integer is a constraint that permits any integer type.
// If future releases of Go add new predeclared integer types,
// this constraint will be modified to include them.
type Integer interface {
Signed | Unsigned
}

// Float is a constraint that permits any floating-point type.
// If future releases of Go add new predeclared floating-point types,
// this constraint will be modified to include them.
type Float interface {
~float32 | ~float64
}

// Complex is a constraint that permits any complex numeric type.
// If future releases of Go add new predeclared complex numeric types,
// this constraint will be modified to include them.
type Complex interface {
~complex64 | ~complex128
}

// Ordered is a constraint that permits any ordered type: any type
// that supports the operators < <= >= >.
// If future releases of Go add new ordered types,
// this constraint will be modified to include them.
type Ordered interface {
Integer | Float | ~string
}
27 changes: 27 additions & 0 deletions gogenerics/constraints/func.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package constraints

type (
// Call is Function Call
Call func()

// Consumer is one input argument and no returns Function
Consumer[T any] func(T)

// BiConsumer is two input arguments and no returns Function
BiConsumer[T, U any] func(T, U)

// UFunc is Unary Function
UFunc[P, R any] func(P) R

// BiFunc is Binary Function
BiFunc[P1, P2, R any] func(P1, P2) R

// Cmp is Compare Function
Cmp[T any] BiFunc[T, T, int]

// Eql is Equal Function
Eql[T any] BiFunc[T, T, bool]

// Less is Less Function
Less[T any] BiFunc[T, T, bool]
)
97 changes: 97 additions & 0 deletions gogenerics/gnumerics/math.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package gnumerics

import "github.com/miniLCT/gosb/gogenerics/constraints"

// Max returns the maximum of two values
func Max[T constraints.Ordered](a, b T) T {
if a > b {
return a
}
return b
}

// MaxCollection returns the maximum value in a collection. Returns zero value when collection is empty
func MaxCollection[T constraints.Ordered](collection []T) T {
var maxC T
l := len(collection)
if l == 0 {
return maxC
}

maxC = collection[0]
for i := 1; i < l; i++ {
c := collection[i]
if c > maxC {
maxC = c
}
}
return maxC
}

// MaxBy returns the maximum value in a collection, using the given comparison function
// If several values are equivalent, the first one is returned
// Returns zero value when collection is empty
func MaxBy[T any](collection []T, cmp func(a T, b T) bool) T {
var maxC T

l := len(collection)
if l == 0 {
return maxC
}

maxC = collection[0]
for i := 1; i < l; i++ {
c := collection[i]
if cmp(c, maxC) {
maxC = c
}
}
return maxC
}

// Min returns the minimum of two values.
func Min[T constraints.Ordered](a, b T) T {
if a < b {
return a
}
return b
}

// MinCollection returns the minimum value in a collection. Returns zero value when collection is empty
func MinCollection[T constraints.Ordered](collection []T) T {
var minC T
l := len(collection)
if l == 0 {
return minC
}

minC = collection[0]
for i := 1; i < l; i++ {
c := collection[i]
if c < minC {
minC = c
}
}
return minC
}

// MinBy returns the minimum value in a collection, using the given comparison function
// If several values are equivalent, the first one is returned
// Returns zero value when collection is empty
func MinBy[T any](collection []T, cmp func(a T, b T) bool) T {
var minC T

l := len(collection)
if l == 0 {
return minC
}

minC = collection[0]
for i := 1; i < l; i++ {
c := collection[i]
if cmp(c, minC) {
minC = c
}
}
return minC
}
103 changes: 103 additions & 0 deletions gogenerics/gnumerics/math_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package gnumerics

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestMax(t *testing.T) {
t.Parallel()
assert := assert.New(t)

resInt := Max(114, 514)
resFloat := Max(100.0, 99.9)
resString := Max("109", "11")

assert.Equal(514, resInt)
assert.Equal(100.00, resFloat)
assert.Equal("11", resString)
}

func TestMin(t *testing.T) {
t.Parallel()
assert := assert.New(t)

resInt := Min(114, 514)
resFloat := Min(100.0, 99.9)
resString := Min("109", "11")

assert.Equal(114, resInt)
assert.Equal(99.9, resFloat)
assert.Equal("109", resString)
}

func TestMaxCollection(t *testing.T) {
t.Parallel()
assert := assert.New(t)

resEmpty := MaxCollection([]int{})
resInt1 := MaxCollection([]int{1})
resInt2 := MaxCollection([]int64{1, 2, 3, 4, 5})
resString := MaxCollection([]string{"11", "109", "100", "a"})
resFloat := MaxCollection([]float64{-100.0, 99.9, 99.8})

assert.Equal(0, resEmpty)
assert.Equal(1, resInt1)
assert.Equal(int64(5), resInt2)
assert.Equal("a", resString)
assert.Equal(99.9, resFloat)
}

func TestMinCollection(t *testing.T) {
t.Parallel()
assert := assert.New(t)

resEmpty := MinCollection([]string{})
resInt1 := MinCollection([]int{1})
resInt2 := MinCollection([]int64{1, 2, 3, 4, 5})
resString := MinCollection([]string{"11", "109", "100", "a"})
resFloat := MinCollection([]float64{-100.0, 99.9, 99.8})

assert.Equal("", resEmpty)
assert.Equal(1, resInt1)
assert.Equal(int64(1), resInt2)
assert.Equal("100", resString)
assert.Equal(-100.0, resFloat)
}

func TestMaxBy(t *testing.T) {
t.Parallel()
assert := assert.New(t)
res1 := MaxBy([]string{"hello", "the", "cruel", "woooooorld"}, func(a, b string) bool {
return len(a) > len(b)
})
res2 := MaxBy([]string{"hello", "the", "cruel", "world"}, func(a, b string) bool {
return len(a) > len(b)
})
res3 := MaxBy([]int{1, 92, -9, 123, -456}, func(a, b int) bool {
return a > b
})

assert.Equal("woooooorld", res1)
assert.Equal("hello", res2)
assert.Equal(123, res3)
}

func TestMinBy(t *testing.T) {
t.Parallel()
assert := assert.New(t)
res1 := MinBy([]string{"hello", "the", "cruel", "woooooorld"}, func(a, b string) bool {
return len(a) < len(b)
})
res2 := MinBy([]string{"hello", "thhhe", "cruel", "world"}, func(a, b string) bool {
return len(a) < len(b)
})
res3 := MinBy([]int{1, 92, -9, 123, -456}, func(a, b int) bool {
return a < b
})

assert.Equal("the", res1)
assert.Equal("hello", res2)
assert.Equal(-456, res3)
}

0 comments on commit e4eab32

Please sign in to comment.