|  | // Copyright 2022 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | package chans | 
|  |  | 
|  | import "runtime" | 
|  |  | 
|  | // Ranger returns a Sender and a Receiver. The Receiver provides a | 
|  | // Next method to retrieve values. The Sender provides a Send method | 
|  | // to send values and a Close method to stop sending values. The Next | 
|  | // method indicates when the Sender has been closed, and the Send | 
|  | // method indicates when the Receiver has been freed. | 
|  | // | 
|  | // This is a convenient way to exit a goroutine sending values when | 
|  | // the receiver stops reading them. | 
|  | func Ranger[T any]() (*Sender[T], *Receiver[T]) { | 
|  | c := make(chan T) | 
|  | d := make(chan bool) | 
|  | s := &Sender[T]{values: c, done: d} | 
|  | r := &Receiver[T]{values: c, done: d} | 
|  | runtime.SetFinalizer(r, r.finalize) | 
|  | return s, r | 
|  | } | 
|  |  | 
|  | // A sender is used to send values to a Receiver. | 
|  | type Sender[T any] struct { | 
|  | values chan<- T | 
|  | done   <-chan bool | 
|  | } | 
|  |  | 
|  | // Send sends a value to the receiver. It returns whether any more | 
|  | // values may be sent; if it returns false the value was not sent. | 
|  | func (s *Sender[T]) Send(v T) bool { | 
|  | select { | 
|  | case s.values <- v: | 
|  | return true | 
|  | case <-s.done: | 
|  | return false | 
|  | } | 
|  | } | 
|  |  | 
|  | // Close tells the receiver that no more values will arrive. | 
|  | // After Close is called, the Sender may no longer be used. | 
|  | func (s *Sender[T]) Close() { | 
|  | close(s.values) | 
|  | } | 
|  |  | 
|  | // A Receiver receives values from a Sender. | 
|  | type Receiver[T any] struct { | 
|  | values <-chan T | 
|  | done   chan<- bool | 
|  | } | 
|  |  | 
|  | // Next returns the next value from the channel. The bool result | 
|  | // indicates whether the value is valid, or whether the Sender has | 
|  | // been closed and no more values will be received. | 
|  | func (r *Receiver[T]) Next() (T, bool) { | 
|  | v, ok := <-r.values | 
|  | return v, ok | 
|  | } | 
|  |  | 
|  | // finalize is a finalizer for the receiver. | 
|  | func (r *Receiver[T]) finalize() { | 
|  | close(r.done) | 
|  | } |