github.com/tursom/GoCollections@v0.3.10/lang/atomic/Reference.go (about) 1 /* 2 * Copyright (c) 2022 tursom. All rights reserved. 3 * Use of this source code is governed by a GPL-3 4 * license that can be found in the LICENSE file. 5 */ 6 7 package atomic 8 9 import ( 10 "sync/atomic" 11 "unsafe" 12 13 "github.com/tursom/GoCollections/lang" 14 15 unsafe2 "github.com/tursom/GoCollections/unsafe" 16 ) 17 18 type ( 19 Pointer = unsafe.Pointer 20 PPointer = *unsafe.Pointer 21 22 // Reference atomizer type T reference 23 Reference[T any] struct { 24 lang.BaseObject 25 p *T 26 } 27 ) 28 29 // NewReference new *Reference[T] init by given reference 30 func NewReference[T any](reference *T) *Reference[T] { 31 return &Reference[T]{p: reference} 32 } 33 34 // ReferenceOf cast **T to *Reference[T] 35 func ReferenceOf[T any](reference **T) *Reference[T] { 36 return unsafe2.ForceCast[Reference[T]](Pointer(reference)) 37 } 38 39 func ReferenceUintptr[T any](reference *uintptr) *Reference[T] { 40 return unsafe2.ForceCast[Reference[T]](Pointer(reference)) 41 } 42 43 func (r *Reference[T]) AsPointer() Pointer { 44 return Pointer(r) 45 } 46 47 func (r *Reference[T]) AsPPointer() PPointer { 48 return PPointer(r.AsPointer()) 49 } 50 51 func (r *Reference[T]) AsUintptr() *TypedUintptr[T] { 52 return unsafe2.ForceCast[TypedUintptr[T]](r.AsPointer()) 53 } 54 55 func (r *Reference[T]) pointer() **T { 56 return &r.p 57 } 58 59 func (r *Reference[T]) Load() (val *T) { 60 return LoadPointer(r.pointer()) 61 } 62 63 func (r *Reference[T]) Store(val *T) { 64 StorePointer(r.pointer(), val) 65 } 66 67 func (r *Reference[T]) Swap(new *T) (old *T) { 68 return SwapPointer(r.pointer(), new) 69 } 70 71 func (r *Reference[T]) CompareAndSwap(old, new *T) (swapped bool) { 72 return CompareAndSwapPointer(r.pointer(), old, new) 73 } 74 75 func AsPPointer[T any](p **T) PPointer { 76 return PPointer(Pointer(p)) 77 } 78 79 func LoadPointer[T any](addr **T) (val *T) { 80 return (*T)(atomic.LoadPointer(AsPPointer(addr))) 81 } 82 83 func StorePointer[T any](addr **T, val *T) { 84 atomic.StorePointer(AsPPointer(addr), Pointer(val)) 85 } 86 87 func SwapPointer[T any](addr **T, new *T) (old *T) { 88 return (*T)(atomic.SwapPointer(AsPPointer(addr), Pointer(new))) 89 } 90 91 func CompareAndSwapPointer[T any](addr **T, old, new *T) (swapped bool) { 92 return atomic.CompareAndSwapPointer(AsPPointer(addr), Pointer(old), Pointer(new)) 93 }