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  }