github.com/mitranim/gg@v0.1.17/lazy_initer.go (about)

     1  package gg
     2  
     3  import "sync"
     4  
     5  /*
     6  Shortcut for type inference. The following is equivalent:
     7  
     8  	NewLazyIniter[Val]()
     9  	new(LazyIniter[Val, Ptr])
    10  */
    11  func NewLazyIniter[Val any, Ptr IniterPtr[Val]]() *LazyIniter[Val, Ptr] {
    12  	return new(LazyIniter[Val, Ptr])
    13  }
    14  
    15  /*
    16  Encapsulates a lazily-initializable value. The first call to `.Get` or `.Ptr`
    17  initializes the underlying value by calling its `.Init` method. Initialization
    18  is performed exactly once. Access is synchronized. All methods are
    19  concurrency-safe. Designed to be embeddable. A zero value is ready to use. When
    20  using this as a struct field, you don't need to explicitly initialize the
    21  field. Contains a mutex and must not be copied.
    22  */
    23  type LazyIniter[Val any, Ptr IniterPtr[Val]] struct {
    24  	val  Opt[Val]
    25  	lock sync.RWMutex
    26  }
    27  
    28  // Returns the underlying value, lazily initializing it on the first call.
    29  func (self *LazyIniter[Val, _]) Get() Val { return *self.Ptr() }
    30  
    31  /*
    32  Returns a pointer to the underlying value, lazily initializing it on the first
    33  call.
    34  */
    35  func (self *LazyIniter[_, Ptr]) Ptr() Ptr {
    36  	if self.inited() {
    37  		return self.ptr()
    38  	}
    39  	return self.init()
    40  }
    41  
    42  func (self *LazyIniter[_, Ptr]) ptr() Ptr { return &self.val.Val }
    43  
    44  func (self *LazyIniter[_, _]) inited() bool {
    45  	self.lock.RLock()
    46  	defer self.lock.RUnlock()
    47  	return self.val.IsNotNull()
    48  }
    49  
    50  func (self *LazyIniter[_, Ptr]) init() Ptr {
    51  	self.lock.Lock()
    52  	defer self.lock.Unlock()
    53  	if self.val.IsNotNull() {
    54  		return self.ptr()
    55  	}
    56  
    57  	Ptr(&self.val.Val).Init()
    58  	self.val.Ok = true
    59  	return self.ptr()
    60  }