mirror of
https://github.com/tursom/GoCollections.git
synced 2024-12-26 07:50:12 +08:00
update atmoic
This commit is contained in:
parent
fed6847099
commit
7bca6fe5cf
@ -11,7 +11,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/tursom/GoCollections/util/unsafe"
|
||||
"github.com/tursom/GoCollections/unsafe"
|
||||
)
|
||||
|
||||
func TestPublisherMessageQueueNode_Sizeof(t *testing.T) {
|
||||
|
15
encoding/hex/hex.go
Normal file
15
encoding/hex/hex.go
Normal file
@ -0,0 +1,15 @@
|
||||
package hex
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/tursom/GoCollections/unsafe"
|
||||
)
|
||||
|
||||
func EncodeToString[T any](arr []T) string {
|
||||
return hex.EncodeToString(unsafe.AsBytes(arr))
|
||||
}
|
||||
|
||||
func DecodeString(s string) ([]byte, error) {
|
||||
return hex.DecodeString(s)
|
||||
}
|
74
lang/Array.go
Normal file
74
lang/Array.go
Normal file
@ -0,0 +1,74 @@
|
||||
package lang
|
||||
|
||||
type (
|
||||
Array[T any] []T
|
||||
|
||||
Int8Array Array[int32]
|
||||
Int16Array Array[int32]
|
||||
Int32Array Array[int32]
|
||||
Int64Array Array[int64]
|
||||
UInt8Array Array[uint32]
|
||||
UInt16Array Array[uint32]
|
||||
UInt32Array Array[uint32]
|
||||
UInt64Array Array[uint64]
|
||||
)
|
||||
|
||||
func (a Array[T]) Array() []T {
|
||||
return a
|
||||
}
|
||||
|
||||
func (a Int8Array) SetBit(bit int, up bool) (old bool) {
|
||||
arrIndex := bit / 8
|
||||
i := &a[arrIndex]
|
||||
|
||||
return SwapBit(i, bit%8, up)
|
||||
}
|
||||
|
||||
func (a Int16Array) SetBit(bit int, up bool) (old bool) {
|
||||
arrIndex := bit / 16
|
||||
i := &a[arrIndex]
|
||||
|
||||
return SwapBit(i, bit%16, up)
|
||||
}
|
||||
|
||||
func (a Int32Array) SetBit(bit int, up bool) (old bool) {
|
||||
arrIndex := bit / 32
|
||||
i := &a[arrIndex]
|
||||
|
||||
return SwapBit(i, bit%32, up)
|
||||
}
|
||||
|
||||
func (a Int64Array) SetBit(bit int, up bool) (old bool) {
|
||||
arrIndex := bit / 64
|
||||
i := &a[arrIndex]
|
||||
|
||||
return SwapBit(i, bit%64, up)
|
||||
}
|
||||
|
||||
func (a UInt8Array) SetBit(bit int, up bool) (old bool) {
|
||||
arrIndex := bit / 8
|
||||
i := &a[arrIndex]
|
||||
|
||||
return SwapBit(i, bit%8, up)
|
||||
}
|
||||
|
||||
func (a UInt16Array) SetBit(bit int, up bool) (old bool) {
|
||||
arrIndex := bit / 16
|
||||
i := &a[arrIndex]
|
||||
|
||||
return SwapBit(i, bit%16, up)
|
||||
}
|
||||
|
||||
func (a UInt32Array) SetBit(bit int, up bool) (old bool) {
|
||||
arrIndex := bit / 32
|
||||
i := &a[arrIndex]
|
||||
|
||||
return SwapBit(i, bit%32, up)
|
||||
}
|
||||
|
||||
func (a UInt64Array) SetBit(bit int, up bool) (old bool) {
|
||||
arrIndex := bit / 64
|
||||
i := &a[arrIndex]
|
||||
|
||||
return SwapBit(i, bit%64, up)
|
||||
}
|
@ -8,7 +8,6 @@ package lang
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func TypeName[T any]() string {
|
||||
@ -54,11 +53,3 @@ func Cast[T any](v any) T {
|
||||
return t
|
||||
}
|
||||
}
|
||||
|
||||
func ForceCast[T any](v unsafe.Pointer) *T {
|
||||
if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return (*T)(v)
|
||||
}
|
||||
}
|
||||
|
@ -12,3 +12,16 @@ type Number interface {
|
||||
ToUInt64() UInt64
|
||||
ToFloat64() Float64
|
||||
}
|
||||
|
||||
func SwapBit[T int32 | int64 | uint32 | uint64](p *T, bit int, new bool) (old bool) {
|
||||
location := T(1) << bit
|
||||
oldValue := *p
|
||||
var newValue T
|
||||
if new {
|
||||
newValue = oldValue | location
|
||||
} else {
|
||||
newValue = oldValue & ^location
|
||||
}
|
||||
*p = newValue
|
||||
return oldValue&newValue != 0
|
||||
}
|
||||
|
@ -6,111 +6,188 @@
|
||||
|
||||
package atomic
|
||||
|
||||
import "github.com/tursom/GoCollections/lang"
|
||||
|
||||
type (
|
||||
Array[T any] struct {
|
||||
atomic Atomic[T]
|
||||
array []T
|
||||
}
|
||||
Int32Array struct {
|
||||
Array[int32]
|
||||
}
|
||||
Int64Array struct {
|
||||
Array[int64]
|
||||
}
|
||||
UInt32Array struct {
|
||||
Array[uint32]
|
||||
}
|
||||
UInt64Array struct {
|
||||
Array[uint64]
|
||||
}
|
||||
Array[T any] lang.Array[*T]
|
||||
Int32Array lang.Array[Int32]
|
||||
Int64Array lang.Array[Int64]
|
||||
UInt32Array lang.Array[UInt32]
|
||||
UInt64Array lang.Array[UInt64]
|
||||
)
|
||||
|
||||
func NewArray[T any](size int) *Array[*T] {
|
||||
return &Array[*T]{
|
||||
atomic: GetAtomic[T](),
|
||||
array: make([]*T, size),
|
||||
}
|
||||
func NewArray[T any](size int) Array[T] {
|
||||
return make([]*T, size)
|
||||
}
|
||||
|
||||
func CapArray[T any](array []*T) *Array[*T] {
|
||||
return &Array[*T]{
|
||||
atomic: GetAtomic[T](),
|
||||
array: array,
|
||||
}
|
||||
func CapArray[T any](array []*T) Array[T] {
|
||||
return array
|
||||
}
|
||||
|
||||
func NewInt32Array(size int) *Int32Array {
|
||||
return &Int32Array{
|
||||
Array[int32]{
|
||||
atomic: Int32F,
|
||||
array: make([]int32, size),
|
||||
},
|
||||
}
|
||||
func NewInt32Array(size int) Int32Array {
|
||||
return make(Int32Array, size)
|
||||
}
|
||||
|
||||
func NewInt64Array(size int) *Int64Array {
|
||||
return &Int64Array{
|
||||
Array[int64]{
|
||||
atomic: Int64F,
|
||||
array: make([]int64, size),
|
||||
},
|
||||
}
|
||||
func NewInt64Array(size int) Int64Array {
|
||||
return make(Int64Array, size)
|
||||
}
|
||||
|
||||
func NewUInt32Array(size int) *UInt32Array {
|
||||
return &UInt32Array{
|
||||
Array[uint32]{
|
||||
atomic: UInt32F,
|
||||
array: make([]uint32, size),
|
||||
},
|
||||
}
|
||||
func NewUInt32Array(size int) UInt32Array {
|
||||
return make(UInt32Array, size)
|
||||
}
|
||||
|
||||
func NewUInt64Array(size int) *UInt64Array {
|
||||
return &UInt64Array{
|
||||
Array[uint64]{
|
||||
atomic: UInt64F,
|
||||
array: make([]uint64, size),
|
||||
},
|
||||
}
|
||||
func NewUInt64Array(size int) UInt64Array {
|
||||
return make(UInt64Array, size)
|
||||
}
|
||||
|
||||
func (a *Array[T]) Len() int {
|
||||
return len(a.array)
|
||||
func (a Array[T]) Len() int {
|
||||
return len(a)
|
||||
}
|
||||
|
||||
func (a *Array[T]) Array() []T {
|
||||
return a.array
|
||||
func (a Array[T]) Array() []*T {
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *Array[T]) Get(index int) T {
|
||||
return a.atomic.Load()(&a.array[index])
|
||||
func (a Array[T]) Get(index int) *T {
|
||||
return GetAtomizer[T]().Load()(&a[index])
|
||||
}
|
||||
|
||||
func (a *Array[T]) Set(index int, p T) {
|
||||
a.atomic.Store()(&a.array[index], p)
|
||||
func (a Int32Array) Get(index int) int32 {
|
||||
return a[index].Load()
|
||||
}
|
||||
|
||||
func (a *Array[T]) Swap(index int, p T) (old T) {
|
||||
return a.atomic.Swap()(&a.array[index], p)
|
||||
func (a Int64Array) Get(index int) int64 {
|
||||
return a[index].Load()
|
||||
}
|
||||
|
||||
func (a *Array[T]) CompareAndSwap(index int, old, new T) (swapped bool) {
|
||||
return a.atomic.CompareAndSwap()(&a.array[index], old, new)
|
||||
func (a UInt32Array) Get(index int) uint32 {
|
||||
return a[index].Load()
|
||||
}
|
||||
|
||||
func (a *Int32Array) Add(index int, value int32) {
|
||||
AddInt32(&a.array[index], value)
|
||||
func (a UInt64Array) Get(index int) uint64 {
|
||||
return a[index].Load()
|
||||
}
|
||||
|
||||
func (a *Int64Array) Add(index int, value int64) {
|
||||
AddInt64(&a.array[index], value)
|
||||
func (a Array[T]) Set(index int, p *T) {
|
||||
GetAtomizer[T]().Store()(&a[index], p)
|
||||
}
|
||||
|
||||
func (a *UInt32Array) Add(index int, value uint32) {
|
||||
AddUInt32(&a.array[index], value)
|
||||
func (a Int32Array) Set(index int, v int32) {
|
||||
a[index].Store(v)
|
||||
}
|
||||
|
||||
func (a *UInt64Array) Add(index int, value uint64) {
|
||||
AddUInt64(&a.array[index], value)
|
||||
func (a Int64Array) Set(index int, v int64) {
|
||||
a[index].Store(v)
|
||||
}
|
||||
|
||||
func (a UInt32Array) Set(index int, v uint32) {
|
||||
a[index].Store(v)
|
||||
}
|
||||
|
||||
func (a UInt64Array) Set(index int, v uint64) {
|
||||
a[index].Store(v)
|
||||
}
|
||||
|
||||
func (a Array[T]) Swap(index int, p *T) (old *T) {
|
||||
return GetAtomizer[T]().Swap()(&a[index], p)
|
||||
}
|
||||
|
||||
func (a Int32Array) Swap(index int, new int32) (old int32) {
|
||||
return a[index].Swap(new)
|
||||
}
|
||||
|
||||
func (a Int64Array) Swap(index int, new int64) (old int64) {
|
||||
return a[index].Swap(new)
|
||||
}
|
||||
|
||||
func (a UInt32Array) Swap(index int, new uint32) (old uint32) {
|
||||
return a[index].Swap(new)
|
||||
}
|
||||
|
||||
func (a UInt64Array) Swap(index int, new uint64) (old uint64) {
|
||||
return a[index].Swap(new)
|
||||
}
|
||||
|
||||
func (a Array[T]) CompareAndSwap(index int, old, new *T) (swapped bool) {
|
||||
return GetAtomizer[T]().CompareAndSwap()(&a[index], old, new)
|
||||
}
|
||||
|
||||
func (a Int32Array) CompareAndSwap(index int, old, new int32) (swapped bool) {
|
||||
return a[index].CompareAndSwap(old, new)
|
||||
}
|
||||
|
||||
func (a Int64Array) CompareAndSwap(index int, old, new int64) (swapped bool) {
|
||||
return a[index].CompareAndSwap(old, new)
|
||||
}
|
||||
|
||||
func (a UInt32Array) CompareAndSwap(index int, old, new uint32) (swapped bool) {
|
||||
return a[index].CompareAndSwap(old, new)
|
||||
}
|
||||
|
||||
func (a UInt64Array) CompareAndSwap(index int, old, new uint64) (swapped bool) {
|
||||
return a[index].CompareAndSwap(old, new)
|
||||
}
|
||||
|
||||
func (a Int32Array) Add(index int, value int32) {
|
||||
a[index].Add(value)
|
||||
}
|
||||
|
||||
func (a Int64Array) Add(index int, value int64) {
|
||||
a[index].Add(value)
|
||||
}
|
||||
|
||||
func (a UInt32Array) Add(index int, value uint32) {
|
||||
a[index].Add(value)
|
||||
}
|
||||
|
||||
func (a UInt64Array) Add(index int, value uint64) {
|
||||
a[index].Add(value)
|
||||
}
|
||||
|
||||
func (a Int32Array) BitLength() int {
|
||||
return len(a) * 32
|
||||
}
|
||||
|
||||
func (a Int64Array) BitLength() int {
|
||||
return len(a) * 64
|
||||
}
|
||||
|
||||
func (a UInt32Array) BitLength() int {
|
||||
return len(a) * 32
|
||||
}
|
||||
|
||||
func (a UInt64Array) BitLength() int {
|
||||
return len(a) * 64
|
||||
}
|
||||
|
||||
func (a Int32Array) SetBit(bit int, up bool) (old bool) {
|
||||
return a[bit/32].SetBit(bit%32, up)
|
||||
}
|
||||
|
||||
func (a Int64Array) SetBit(bit int, up bool) (old bool) {
|
||||
return a[bit/64].SetBit(bit%64, up)
|
||||
}
|
||||
|
||||
func (a UInt32Array) SetBit(bit int, up bool) (old bool) {
|
||||
return a[bit/32].SetBit(bit%32, up)
|
||||
}
|
||||
|
||||
func (a UInt64Array) SetBit(bit int, up bool) (old bool) {
|
||||
return a[bit/64].SetBit(bit%64, up)
|
||||
}
|
||||
|
||||
func (a Int32Array) CompareAndSwapBit(bit int, old, new bool) (swapped bool) {
|
||||
return a[bit/32].CompareAndSwapBit(bit%32, old, new)
|
||||
}
|
||||
|
||||
func (a Int64Array) CompareAndSwapBit(bit int, old, new bool) (swapped bool) {
|
||||
return a[bit/64].CompareAndSwapBit(bit%64, old, new)
|
||||
}
|
||||
|
||||
func (a UInt32Array) CompareAndSwapBit(bit int, old, new bool) (swapped bool) {
|
||||
return a[bit/32].CompareAndSwapBit(bit%32, old, new)
|
||||
}
|
||||
|
||||
func (a UInt64Array) CompareAndSwapBit(bit int, old, new bool) (swapped bool) {
|
||||
return a[bit/64].CompareAndSwapBit(bit%64, old, new)
|
||||
}
|
||||
|
21
lang/atomic/Array_test.go
Normal file
21
lang/atomic/Array_test.go
Normal file
@ -0,0 +1,21 @@
|
||||
package atomic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/tursom/GoCollections/encoding/hex"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
func TestNewInt32Array_SetBit(t *testing.T) {
|
||||
fmt.Println(reflect.TypeOf(lang.Nil[atomizerImpl[int]]()).Align())
|
||||
|
||||
array := NewInt32Array(16)
|
||||
for i := 0; i < 16; i++ {
|
||||
array.SetBit(10*i, true)
|
||||
}
|
||||
fmt.Println(array)
|
||||
fmt.Println(hex.EncodeToString(array))
|
||||
}
|
@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
Atomizer[T any] interface {
|
||||
Atomic[T any] interface {
|
||||
Swap(new T) (old T)
|
||||
CompareAndSwap(old, new T) (swapped bool)
|
||||
Load() (val T)
|
||||
@ -26,91 +26,91 @@ type (
|
||||
CompareAndSwapBit(bit int, old, new bool) (swapped bool)
|
||||
}
|
||||
|
||||
Atomic[T any] interface {
|
||||
Atomizer[T any] interface {
|
||||
Swap() func(addr *T, new T) (old T)
|
||||
CompareAndSwap() func(addr *T, old, new T) (swapped bool)
|
||||
Load() func(addr *T) (val T)
|
||||
Store() func(addr *T, val T)
|
||||
}
|
||||
|
||||
atomicImpl[T any] struct {
|
||||
atomizerImpl[T any] struct {
|
||||
swap func(addr *T, new T) (old T)
|
||||
compareAndSwap func(addr *T, old, new T) (swapped bool)
|
||||
load func(addr *T) (val T)
|
||||
store func(addr *T, val T)
|
||||
}
|
||||
|
||||
atomicTyped[T any] struct {
|
||||
}
|
||||
)
|
||||
|
||||
//goland:noinspection GoUnusedGlobalVariable
|
||||
var (
|
||||
Int32F Atomic[int32] = &atomicImpl[int32]{
|
||||
int32Atomizer = &atomizerImpl[int32]{
|
||||
SwapInt32,
|
||||
CompareAndSwapInt32,
|
||||
LoadInt32,
|
||||
StoreInt32,
|
||||
}
|
||||
Int64F Atomic[int64] = &atomicImpl[int64]{
|
||||
int64Atomizer = &atomizerImpl[int64]{
|
||||
SwapInt64,
|
||||
CompareAndSwapInt64,
|
||||
LoadInt64,
|
||||
StoreInt64,
|
||||
}
|
||||
UInt32F Atomic[uint32] = &atomicImpl[uint32]{
|
||||
uint32Atomizer = &atomizerImpl[uint32]{
|
||||
SwapUInt32,
|
||||
CompareAndSwapUInt32,
|
||||
LoadUint32,
|
||||
StoreUInt32,
|
||||
}
|
||||
UInt64F Atomic[uint64] = &atomicImpl[uint64]{
|
||||
uint64Atomizer = &atomizerImpl[uint64]{
|
||||
SwapUInt64,
|
||||
CompareAndSwapUInt64,
|
||||
LoadUint64,
|
||||
StoreUInt64,
|
||||
}
|
||||
PointerF Atomic[unsafe.Pointer] = &atomicImpl[unsafe.Pointer]{
|
||||
UnsafeSwapPointer,
|
||||
UnsafeCompareAndSwapPointer,
|
||||
UnsafeLoadPointer,
|
||||
UnsafeStorePointer,
|
||||
pointerAtomizer = &atomizerImpl[unsafe.Pointer]{
|
||||
atomic.SwapPointer,
|
||||
atomic.CompareAndSwapPointer,
|
||||
atomic.LoadPointer,
|
||||
atomic.StorePointer,
|
||||
}
|
||||
)
|
||||
|
||||
func GetAtomic[T any]() Atomic[*T] {
|
||||
return atomicTyped[T]{}
|
||||
func Int32Atomizer() Atomizer[int32] {
|
||||
return int32Atomizer
|
||||
}
|
||||
|
||||
func (a atomicTyped[T]) Swap() func(addr **T, new *T) (old *T) {
|
||||
return SwapPointer[T]
|
||||
func Int64Atomizer() Atomizer[int64] {
|
||||
return int64Atomizer
|
||||
}
|
||||
|
||||
func (a atomicTyped[T]) CompareAndSwap() func(addr **T, old *T, new *T) (swapped bool) {
|
||||
return CompareAndSwapPointer[T]
|
||||
func UInt32Atomizer() Atomizer[uint32] {
|
||||
return uint32Atomizer
|
||||
}
|
||||
|
||||
func (a atomicTyped[T]) Load() func(addr **T) (val *T) {
|
||||
return LoadPointer[T]
|
||||
func UInt64Atomizer() Atomizer[uint64] {
|
||||
return uint64Atomizer
|
||||
}
|
||||
|
||||
func (a atomicTyped[T]) Store() func(addr **T, val *T) {
|
||||
return StorePointer[T]
|
||||
func PointerAtomizer() Atomizer[unsafe.Pointer] {
|
||||
return pointerAtomizer
|
||||
}
|
||||
|
||||
func (a *atomicImpl[T]) Swap() func(addr *T, new T) (old T) {
|
||||
func GetAtomizer[T any]() Atomizer[*T] {
|
||||
return (*atomizerImpl[*T])(unsafe.Pointer(pointerAtomizer))
|
||||
}
|
||||
|
||||
func (a *atomizerImpl[T]) Swap() func(addr *T, new T) (old T) {
|
||||
return a.swap
|
||||
}
|
||||
|
||||
func (a *atomicImpl[T]) CompareAndSwap() func(addr *T, old T, new T) (swapped bool) {
|
||||
func (a *atomizerImpl[T]) CompareAndSwap() func(addr *T, old T, new T) (swapped bool) {
|
||||
return a.compareAndSwap
|
||||
}
|
||||
|
||||
func (a *atomicImpl[T]) Load() func(addr *T) (val T) {
|
||||
func (a *atomizerImpl[T]) Load() func(addr *T) (val T) {
|
||||
return a.load
|
||||
}
|
||||
|
||||
func (a *atomicImpl[T]) Store() func(addr *T, val T) {
|
||||
func (a *atomizerImpl[T]) Store() func(addr *T, val T) {
|
||||
return a.store
|
||||
}
|
||||
|
||||
|
15
lang/atomic/Atomic_test.go
Normal file
15
lang/atomic/Atomic_test.go
Normal file
@ -0,0 +1,15 @@
|
||||
package atomic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetAtomizer(t *testing.T) {
|
||||
atomizer := GetAtomizer[int32]()
|
||||
var ref *int32
|
||||
var obj int32 = 1
|
||||
atomizer.CompareAndSwap()(&ref, nil, &obj)
|
||||
|
||||
fmt.Println(*ref)
|
||||
}
|
@ -6,19 +6,17 @@
|
||||
|
||||
package atomic
|
||||
|
||||
type Bool struct {
|
||||
i Int32
|
||||
}
|
||||
type Bool Int32
|
||||
|
||||
func (v *Bool) Load() (val bool) {
|
||||
return v.i.Load() != 0
|
||||
return (*Int32)(v).Load() != 0
|
||||
}
|
||||
|
||||
func (v *Bool) Store(val bool) {
|
||||
if val {
|
||||
v.i.Store(1)
|
||||
(*Int32)(v).Store(1)
|
||||
} else {
|
||||
v.i.Store(0)
|
||||
(*Int32)(v).Store(0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +25,7 @@ func (v *Bool) Swap(new bool) (old bool) {
|
||||
if new {
|
||||
n = 1
|
||||
}
|
||||
return v.i.Swap(n) != 0
|
||||
return (*Int32)(v).Swap(n) != 0
|
||||
}
|
||||
|
||||
func (v *Bool) CompareAndSwap(old, new bool) (swapped bool) {
|
||||
@ -39,5 +37,5 @@ func (v *Bool) CompareAndSwap(old, new bool) (swapped bool) {
|
||||
if new {
|
||||
n = 1
|
||||
}
|
||||
return v.i.CompareAndSwap(o, n)
|
||||
return (*Int32)(v).CompareAndSwap(o, n)
|
||||
}
|
||||
|
@ -42,10 +42,10 @@ func (v *Float32) CompareAndSwap(old, new float32) (swapped bool) {
|
||||
}
|
||||
|
||||
func (v *Float32) Add(f float32) (new float32) {
|
||||
old := float32(*v)
|
||||
old := v.Load()
|
||||
new = old + f
|
||||
for !v.CompareAndSwap(old, new) {
|
||||
old = float32(*v)
|
||||
old = v.Load()
|
||||
new = old + f
|
||||
}
|
||||
|
||||
|
@ -42,10 +42,10 @@ func (v *Float64) CompareAndSwap(old, new float64) (swapped bool) {
|
||||
}
|
||||
|
||||
func (v *Float64) Add(f float64) (new float64) {
|
||||
old := float64(*v)
|
||||
old := v.Load()
|
||||
new = old + f
|
||||
for !v.CompareAndSwap(old, new) {
|
||||
old = float64(*v)
|
||||
old = v.Load()
|
||||
new = old + f
|
||||
}
|
||||
|
||||
|
@ -8,12 +8,9 @@ package atomic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
func TestInt32_SetBit(t *testing.T) {
|
||||
@ -56,14 +53,3 @@ func TestInt32_CompareAndSwapBit(t *testing.T) {
|
||||
time.Sleep(1 * time.Second)
|
||||
fmt.Println(i.Load())
|
||||
}
|
||||
|
||||
func TestTypeConv(t *testing.T) {
|
||||
var intV lang.Int32
|
||||
var i any = intV
|
||||
_, ok := i.(lang.AsInt32)
|
||||
fmt.Println(reflect.TypeOf(i), ok)
|
||||
|
||||
i = &intV
|
||||
_, ok = i.(lang.AsInt32)
|
||||
fmt.Println(reflect.TypeOf(i), ok)
|
||||
}
|
||||
|
@ -11,21 +11,15 @@ import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
//goland:noinspection GoUnusedGlobalVariable
|
||||
var (
|
||||
UnsafeLoadPointer = atomic.LoadPointer
|
||||
UnsafeStorePointer = atomic.StorePointer
|
||||
UnsafeSwapPointer = atomic.SwapPointer
|
||||
UnsafeCompareAndSwapPointer = atomic.CompareAndSwapPointer
|
||||
unsafe2 "github.com/tursom/GoCollections/unsafe"
|
||||
)
|
||||
|
||||
type (
|
||||
Pointer = unsafe.Pointer
|
||||
PPointer = *unsafe.Pointer
|
||||
|
||||
// Reference atomic type T reference
|
||||
// Reference atomizer type T reference
|
||||
Reference[T any] struct {
|
||||
lang.BaseObject
|
||||
p *T
|
||||
@ -34,16 +28,16 @@ type (
|
||||
|
||||
// NewReference new *Reference[T] init by given reference
|
||||
func NewReference[T any](reference *T) *Reference[T] {
|
||||
return lang.ForceCast[Reference[T]](Pointer(&reference))
|
||||
return unsafe2.ForceCast[Reference[T]](Pointer(&reference))
|
||||
}
|
||||
|
||||
// ReferenceOf cast **T to *Reference[T]
|
||||
func ReferenceOf[T any](reference **T) *Reference[T] {
|
||||
return lang.ForceCast[Reference[T]](Pointer(reference))
|
||||
return unsafe2.ForceCast[Reference[T]](Pointer(reference))
|
||||
}
|
||||
|
||||
func ReferenceUintptr[T any](reference *uintptr) *Reference[T] {
|
||||
return lang.ForceCast[Reference[T]](Pointer(reference))
|
||||
return unsafe2.ForceCast[Reference[T]](Pointer(reference))
|
||||
}
|
||||
|
||||
func (r *Reference[T]) AsPointer() Pointer {
|
||||
@ -55,7 +49,7 @@ func (r *Reference[T]) AsPPointer() PPointer {
|
||||
}
|
||||
|
||||
func (r *Reference[T]) AsUintptr() *TypedUintptr[T] {
|
||||
return lang.ForceCast[TypedUintptr[T]](r.AsPointer())
|
||||
return unsafe2.ForceCast[TypedUintptr[T]](r.AsPointer())
|
||||
}
|
||||
|
||||
func (r *Reference[T]) pointer() **T {
|
||||
|
@ -9,7 +9,7 @@ package atomic
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"github.com/tursom/GoCollections/unsafe"
|
||||
)
|
||||
|
||||
type (
|
||||
@ -17,8 +17,8 @@ type (
|
||||
TypedUintptr[T any] Uintptr
|
||||
)
|
||||
|
||||
func (p Uintptr) Raw() uintptr {
|
||||
return uintptr(p)
|
||||
func (p *Uintptr) Raw() uintptr {
|
||||
return uintptr(*p)
|
||||
}
|
||||
|
||||
func (p *Uintptr) RawP() *uintptr {
|
||||
@ -48,8 +48,8 @@ func (p *Uintptr) CompareAndSwap(old, new Uintptr) (swapped bool) {
|
||||
return atomic.CompareAndSwapUintptr((*uintptr)(p), uintptr(old), uintptr(new))
|
||||
}
|
||||
|
||||
func (p TypedUintptr[T]) Raw() uintptr {
|
||||
return uintptr(p)
|
||||
func (p *TypedUintptr[T]) Raw() uintptr {
|
||||
return uintptr(*p)
|
||||
}
|
||||
|
||||
func (p *TypedUintptr[T]) RawP() *uintptr {
|
||||
@ -65,11 +65,11 @@ func (p *TypedUintptr[T]) AsPPointer() PPointer {
|
||||
}
|
||||
|
||||
func (tp *TypedUintptr[T]) AsReference() *Reference[T] {
|
||||
return lang.ForceCast[Reference[T]](Pointer(tp))
|
||||
return unsafe.ForceCast[Reference[T]](Pointer(tp))
|
||||
}
|
||||
|
||||
func (tp TypedUintptr[T]) Uintptr() Uintptr {
|
||||
return Uintptr(tp)
|
||||
func (tp *TypedUintptr[T]) Uintptr() Uintptr {
|
||||
return Uintptr(*tp)
|
||||
}
|
||||
|
||||
func (tp *TypedUintptr[T]) PUintptr() *Uintptr {
|
||||
|
44
unsafe/unsafe.go
Normal file
44
unsafe/unsafe.go
Normal file
@ -0,0 +1,44 @@
|
||||
package unsafe
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
type slice struct {
|
||||
array unsafe.Pointer
|
||||
len int
|
||||
cap int
|
||||
}
|
||||
|
||||
func ForceCast[T any](v unsafe.Pointer) *T {
|
||||
if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return (*T)(v)
|
||||
}
|
||||
}
|
||||
|
||||
func Sizeof[T any]() uintptr {
|
||||
return unsafe.Sizeof(lang.Nil[T]())
|
||||
}
|
||||
|
||||
// AsBytes cast any slice as []byte with same pinter, real len and real cap
|
||||
func AsBytes[T any](arr []T) []byte {
|
||||
sarr := *ForceCast[slice](unsafe.Pointer(&arr))
|
||||
typeAlign := reflect.TypeOf(lang.Nil[T]()).Align()
|
||||
asBytes := unsafe.Pointer(&slice{
|
||||
array: sarr.array,
|
||||
len: sarr.len * typeAlign,
|
||||
cap: sarr.cap * typeAlign,
|
||||
})
|
||||
|
||||
return *ForceCast[[]byte](asBytes)
|
||||
}
|
||||
|
||||
// AsString cast bytes as string
|
||||
func AsString(bytes []byte) string {
|
||||
return *ForceCast[string](unsafe.Pointer(&bytes))
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022 tursom. All rights reserved.
|
||||
* Use of this source code is governed by a GPL-3
|
||||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package unsafe
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
func Sizeof[T any]() uintptr {
|
||||
return unsafe.Sizeof(lang.Nil[T]())
|
||||
}
|
Loading…
Reference in New Issue
Block a user