mirror of
https://github.com/tursom/GoCollections.git
synced 2025-03-13 17:00:18 +08:00
94 lines
2.1 KiB
Go
94 lines
2.1 KiB
Go
/*
|
|
* 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 atomic
|
|
|
|
import (
|
|
"sync/atomic"
|
|
"unsafe"
|
|
|
|
"github.com/tursom/GoCollections/lang"
|
|
|
|
unsafe2 "github.com/tursom/GoCollections/unsafe"
|
|
)
|
|
|
|
type (
|
|
Pointer = unsafe.Pointer
|
|
PPointer = *unsafe.Pointer
|
|
|
|
// Reference atomizer type T reference
|
|
Reference[T any] struct {
|
|
lang.BaseObject
|
|
p *T
|
|
}
|
|
)
|
|
|
|
// NewReference new *Reference[T] init by given reference
|
|
func NewReference[T any](reference *T) *Reference[T] {
|
|
return &Reference[T]{p: reference}
|
|
}
|
|
|
|
// ReferenceOf cast **T to *Reference[T]
|
|
func ReferenceOf[T any](reference **T) *Reference[T] {
|
|
return unsafe2.ForceCast[Reference[T]](Pointer(reference))
|
|
}
|
|
|
|
func ReferenceUintptr[T any](reference *uintptr) *Reference[T] {
|
|
return unsafe2.ForceCast[Reference[T]](Pointer(reference))
|
|
}
|
|
|
|
func (r *Reference[T]) AsPointer() Pointer {
|
|
return Pointer(r)
|
|
}
|
|
|
|
func (r *Reference[T]) AsPPointer() PPointer {
|
|
return PPointer(r.AsPointer())
|
|
}
|
|
|
|
func (r *Reference[T]) AsUintptr() *TypedUintptr[T] {
|
|
return unsafe2.ForceCast[TypedUintptr[T]](r.AsPointer())
|
|
}
|
|
|
|
func (r *Reference[T]) pointer() **T {
|
|
return &r.p
|
|
}
|
|
|
|
func (r *Reference[T]) Load() (val *T) {
|
|
return LoadPointer(r.pointer())
|
|
}
|
|
|
|
func (r *Reference[T]) Store(val *T) {
|
|
StorePointer(r.pointer(), val)
|
|
}
|
|
|
|
func (r *Reference[T]) Swap(new *T) (old *T) {
|
|
return SwapPointer(r.pointer(), new)
|
|
}
|
|
|
|
func (r *Reference[T]) CompareAndSwap(old, new *T) (swapped bool) {
|
|
return CompareAndSwapPointer(r.pointer(), old, new)
|
|
}
|
|
|
|
func AsPPointer[T any](p **T) PPointer {
|
|
return PPointer(Pointer(p))
|
|
}
|
|
|
|
func LoadPointer[T any](addr **T) (val *T) {
|
|
return (*T)(atomic.LoadPointer(AsPPointer(addr)))
|
|
}
|
|
|
|
func StorePointer[T any](addr **T, val *T) {
|
|
atomic.StorePointer(AsPPointer(addr), Pointer(val))
|
|
}
|
|
|
|
func SwapPointer[T any](addr **T, new *T) (old *T) {
|
|
return (*T)(atomic.SwapPointer(AsPPointer(addr), Pointer(new)))
|
|
}
|
|
|
|
func CompareAndSwapPointer[T any](addr **T, old, new *T) (swapped bool) {
|
|
return atomic.CompareAndSwapPointer(AsPPointer(addr), Pointer(old), Pointer(new))
|
|
}
|