mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-03 20:07:38 +03:00
Test Comparable interface
This commit is contained in:
parent
51fce3d954
commit
d002d5ba3b
6 changed files with 78 additions and 16 deletions
7
common/cache/lrucache.go
vendored
7
common/cache/lrucache.go
vendored
|
@ -6,6 +6,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/x/list"
|
||||
)
|
||||
|
||||
|
@ -69,8 +70,7 @@ func New[K comparable, V any](options ...Option[K, V]) *LruCache[K, V] {
|
|||
func (c *LruCache[K, V]) Load(key K) (V, bool) {
|
||||
entry := c.get(key)
|
||||
if entry == nil {
|
||||
var defaultValue V
|
||||
return defaultValue, false
|
||||
return common.DefaultValue[V](), false
|
||||
}
|
||||
value := entry.value
|
||||
|
||||
|
@ -154,8 +154,7 @@ create:
|
|||
func (c *LruCache[K, V]) LoadWithExpire(key K) (V, time.Time, bool) {
|
||||
entry := c.get(key)
|
||||
if entry == nil {
|
||||
var defaultValue V
|
||||
return defaultValue, time.Time{}, false
|
||||
return common.DefaultValue[V](), time.Time{}, false
|
||||
}
|
||||
|
||||
return entry.value, time.Unix(entry.expires, 0), true
|
||||
|
|
40
common/comparable.go
Normal file
40
common/comparable.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package common
|
||||
|
||||
type Comparable[T any] interface {
|
||||
Equals(other T) bool
|
||||
}
|
||||
|
||||
func Equals[T Comparable[T]](obj T, other T) bool {
|
||||
var anyObj any = obj
|
||||
var anyOther any = other
|
||||
if anyObj == nil && anyOther == nil {
|
||||
return true
|
||||
} else if anyObj == nil || anyOther == nil {
|
||||
return false
|
||||
}
|
||||
return obj.Equals(other)
|
||||
}
|
||||
|
||||
func IsEmptyByEquals[T Comparable[T]](obj T) bool {
|
||||
return obj.Equals(DefaultValue[T]())
|
||||
}
|
||||
|
||||
func ComparablePtrEquals[T comparable](obj *T, other *T) bool {
|
||||
return *obj == *other
|
||||
}
|
||||
|
||||
func PtrEquals[T Comparable[T]](obj *T, other *T) bool {
|
||||
return Equals(*obj, *other)
|
||||
}
|
||||
|
||||
func ComparableSliceEquals[T comparable](arr []T, otherArr []T) bool {
|
||||
return len(arr) == len(otherArr) && AllIndexed(arr, func(index int, it T) bool {
|
||||
return it == otherArr[index]
|
||||
})
|
||||
}
|
||||
|
||||
func SliceEquals[T Comparable[T]](arr []T, otherArr []T) bool {
|
||||
return len(arr) == len(otherArr) && AllIndexed(arr, func(index int, it T) bool {
|
||||
return Equals(it, otherArr[index])
|
||||
})
|
||||
}
|
|
@ -16,6 +16,15 @@ func Any[T any](array []T, block func(it T) bool) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func AnyIndexed[T any](array []T, block func(index int, it T) bool) bool {
|
||||
for i, it := range array {
|
||||
if block(i, it) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func All[T any](array []T, block func(it T) bool) bool {
|
||||
for _, it := range array {
|
||||
if !block(it) {
|
||||
|
@ -25,6 +34,15 @@ func All[T any](array []T, block func(it T) bool) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func AllIndexed[T any](array []T, block func(index int, it T) bool) bool {
|
||||
for i, it := range array {
|
||||
if !block(i, it) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func Contains[T comparable](arr []T, target T) bool {
|
||||
for i := range arr {
|
||||
if target == arr[i] {
|
||||
|
@ -66,8 +84,7 @@ func Find[T any](arr []T, block func(it T) bool) T {
|
|||
return it
|
||||
}
|
||||
}
|
||||
var defaultValue T
|
||||
return defaultValue
|
||||
return DefaultValue[T]()
|
||||
}
|
||||
|
||||
//go:norace
|
||||
|
@ -164,15 +181,18 @@ func PtrOrNil[T any](ptr *T) any {
|
|||
|
||||
func PtrValueOrDefault[T any](ptr *T) T {
|
||||
if ptr == nil {
|
||||
var defaultValue T
|
||||
return defaultValue
|
||||
return DefaultValue[T]()
|
||||
}
|
||||
return *ptr
|
||||
}
|
||||
|
||||
func IsEmpty[T comparable](obj T) bool {
|
||||
return obj == DefaultValue[T]()
|
||||
}
|
||||
|
||||
func DefaultValue[T any]() T {
|
||||
var defaultValue T
|
||||
return obj == defaultValue
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func Close(closers ...any) error {
|
||||
|
|
|
@ -11,6 +11,5 @@ func Cast[T any](obj any) (T, bool) {
|
|||
if u, ok := obj.(WithUpstream); ok {
|
||||
return Cast[T](u.Upstream())
|
||||
}
|
||||
var defaultValue T
|
||||
return defaultValue, false
|
||||
return DefaultValue[T](), false
|
||||
}
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
package list
|
||||
|
||||
import "github.com/sagernet/sing/common"
|
||||
|
||||
func (l List[T]) Size() int {
|
||||
return l.len
|
||||
}
|
||||
|
||||
func (l List[T]) IsEmpty() bool {
|
||||
return l.len == 0
|
||||
}
|
||||
|
||||
func (l *List[T]) PopBack() T {
|
||||
if l.len == 0 {
|
||||
var defaultValue T
|
||||
return defaultValue
|
||||
return common.DefaultValue[T]()
|
||||
}
|
||||
entry := l.root.prev
|
||||
l.remove(entry)
|
||||
|
@ -16,8 +21,7 @@ func (l *List[T]) PopBack() T {
|
|||
|
||||
func (l *List[T]) PopFront() T {
|
||||
if l.len == 0 {
|
||||
var defaultValue T
|
||||
return defaultValue
|
||||
return common.DefaultValue[T]()
|
||||
}
|
||||
entry := l.root.next
|
||||
l.remove(entry)
|
||||
|
|
|
@ -130,7 +130,7 @@ func (l *List[T]) move(e, at *Element[T]) {
|
|||
// Remove removes e from l if e is an element of list l.
|
||||
// It returns the element value e.Value.
|
||||
// The element must not be nil.
|
||||
func (l *List[T]) Remove(e *Element[T]) any {
|
||||
func (l *List[T]) Remove(e *Element[T]) T {
|
||||
if e.list == l {
|
||||
// if e.list == l, l must have been initialized when e was inserted
|
||||
// in l or l == nil (e is a zero Element) and l.remove will crash
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue