 
   let produce: () async -> Element?
 
-  /// Construct a AsyncStream buffering given an Element type.
-  ///
-  /// - Parameter elementType: The type the AsyncStream will produce.
-  /// - Parameter maxBufferedElements: The maximum number of elements to
-  ///   hold in the buffer past any checks for continuations being resumed.
-  /// - Parameter build: The work associated with yielding values to the 
-  ///   AsyncStream.
-  ///
-  /// The maximum number of pending elements limited by dropping the oldest
-  /// value when a new value comes in if the buffer would exceed the limit
-  /// placed upon it. By default this limit is unlimited.
-  ///
-  /// The build closure passes in a Continuation which can be used in
-  /// concurrent contexts. It is thread safe to send and finish; all calls are
-  /// to the continuation are serialized, however calling this from multiple
-  /// concurrent contexts could result in out of order delivery.
+  /// Constructs an asynchronous stream for an element type, using the
+  /// specified buffering policy and element-producing closure.
+  ///
+  /// - Parameters:
+  ///    - elementType: The type of element the `AsyncStream` produces.
+  ///    - bufferingPolicy: A `Continuation.BufferingPolicy` value to
+  ///       set the stream's buffering behavior. By default, the stream buffers an
+  ///       unlimited number of elements. You can also set the policy to buffer a
+  ///       specified number of oldest or newest elements.
+  ///    - build: A custom closure that yields values to the
+  ///       `AsyncStream`. This closure receives an `AsyncStream.Continuation`
+  ///       instance that it uses to provide elements to the stream and terminate the
+  ///       stream when finished.
+  ///
+  /// The `AsyncStream.Continuation` received by the `build` closure is
+  /// appropriate for use in concurrent contexts. It is thread safe to send and
+  /// finish; all calls to the continuation are serialized. However, calling
+  /// this from multiple concurrent contexts could result in out-of-order
+  /// delivery.
+  ///
+  /// The following example shows an `AsyncStream` created with this
+  /// initializer that produces 100 random numbers on a one-second interval,
+  /// calling `yield(_:)` to deliver each element to the awaiting call point.
+  /// When the `for` loop exits and the stream finishes by calling the
+  /// continuation's `finish()` method.
+  ///
+  ///     let stream = AsyncStream<Int>(Int.self,
+  ///                                   bufferingPolicy: .bufferingNewest(5)) { continuation in
+  ///             Task.detached {
+  ///                 for _ in 0..<100 {
+  ///                     await Task.sleep(1 * 1_000_000_000)
+  ///                     continuation.yield(Int.random(in: 1...10))
+  ///                 }
+  ///                 continuation.finish()
+  ///             }
+  ///         }
+  ///
+  ///     // Call point:
+  ///     for await random in stream {
+  ///         print ("\(random)")
+  ///     }
+  ///
   public init(
     _ elementType: Element.Type = Element.self,
     bufferingPolicy limit: Continuation.BufferingPolicy = .unbounded,


import Swift

/// An ordered, asynchronously generated sequence of elements.
///
/// AsyncStream is an interface type to adapt from code producing values to an
/// asynchronous context iterating them. This is intended to be used to allow
/// callback or delegation based APIs to participate with async/await.
///
/// When values are produced from a non async/await source there is a
/// consideration that must be made on behavioral characteristics of how that
/// production of values interacts with the iteration. AsyncStream offers a
/// initialization strategy that provides a method of yielding values into
/// iteration.
///
/// AsyncStream can be initialized with the option to buffer to a given limit.
/// The default value for this limit is Int.max. The buffering is only for
/// values that have yet to be consumed by iteration. Values can be yielded in
/// case to the continuation passed into the build closure. That continuation
/// is Sendable, in that it is intended to be used from concurrent contexts
/// external to the iteration of the AsyncStream.
///
/// A trivial use case producing values from a detached task would work as such:
///
///     let digits = AsyncStream(Int.self) { continuation in
///       detach {
///         for digit in 0..<10 {
///           continuation.yield(digit)
///         }
///         continuation.finish()
///       }
///     }
///
///     for await digit in digits {
///       print(digit)
///     }
///
@available(SwiftStdlib 5.1, *)
public struct AsyncStream<Element> {
  public struct Continuation: Sendable {
    /// Indication of the type of termination informed to
    /// `onTermination`.
    public enum Termination {
      
      /// The stream was finished via the `finish` method
      case finished
      
      /// The stream was cancelled
      case cancelled
    }
    
    /// A result of yielding values.
    public enum YieldResult {
      
      /// When a value is successfully enqueued, either buffered
      /// or immediately consumed to resume a pending call to next
      /// and a count of remaining slots available in the buffer at
      /// the point in time of yielding. Note: transacting upon the
      /// remaining count is only valid when then calls to yield are
      /// mutually exclusive.
      case enqueued(remaining: Int)
      
      /// Yielding resulted in not buffering an element because the
      /// buffer was full. The element is the dropped value.
      case dropped(Element)
      
      /// Indication that the continuation was yielded when the
      /// stream was already in a terminal state: either by cancel or
      /// by finishing.
      case terminated
    }
    
    /// A strategy that handles exhaustion of a buffer’s capacity.
    public enum BufferingPolicy {
      case unbounded
      
      /// When the buffer is full, discard the newly received element.
      /// This enforces keeping the specified amount of oldest values.
      case bufferingOldest(Int)
      
      /// When the buffer is full, discard the oldest element in the buffer.
      /// This enforces keeping the specified amount of newest values.
      case bufferingNewest(Int)
    }

    let storage: _Storage

    /// Resume the task awaiting the next iteration point by having it return
    /// normally from its suspension point or buffer the value if no awaiting
    /// next iteration is active.
    ///
    /// - Parameter value: The value to yield from the continuation.
    ///
    /// This can be called more than once and returns to the caller immediately
    /// without blocking for any awaiting consumption from the iteration.

    }

    /// Resume the task awaiting the next iteration point by having it return
    /// nil, which signifies the end of the iteration.
    ///
    /// Calling this function more than once has no effect. After calling
    /// finish, the stream enters a terminal state and doesn't produces any additional
    /// elements.
    public func finish() {
      storage.finish()
    }

    /// A callback to invoke when canceling iteration of an asynchronous
    /// stream.
    ///
    /// If an `onTermination` callback is set, using task cancellation to
    /// terminate iteration of an `AsyncStream` results in a call to this
    /// callback.
    ///
    /// Canceling an active iteration invokes the `onTermination` callback
    /// first, then resumes by yielding `nil`. This means that you can perform
    /// needed cleanup in the cancellation handler. After reaching a terminal
    /// state as a result of cancellation, the `AsyncStream` sets the callback
    /// to `nil`.
    public var onTermination: (@Sendable (Termination) -> Void)? {
      get {
        return storage.getOnTermination()
