@frozen
public struct Deque {
  @usableFromInline
  internal typealias _Slot = _DequeSlot

  @usableFromInline
  internal var _storage: _Storage

  @inlinable
  internal init(_storage: _Storage) {
    self._storage = _storage
  }
  
  @inlinable
  public init(minimumCapacity: Int) {
    self._storage = _Storage(minimumCapacity: minimumCapacity)
  }
}

@usableFromInline
@frozen
internal struct _DequeSlot {
  @usableFromInline
  internal var position: Int

  @inlinable
  @inline(__always)
  init(at position: Int) {
    assert(position >= 0)
    self.position = position
  }
}

extension _DequeSlot {
  @inlinable
  @inline(__always)
  internal static var zero: Self { Self(at: 0) }

  @inlinable
  @inline(__always)
  internal func advanced(by delta: Int) -> Self {
    Self(at: position &+ delta)
  }

  @inlinable
  @inline(__always)
  internal func orIfZero(_ value: Int) -> Self {
    guard position > 0 else { return Self(at: value) }
    return self
  }
}

extension _DequeSlot: CustomStringConvertible {
  @usableFromInline
  internal var description: String {
    "@\(position)"
  }
}

extension _DequeSlot: Equatable {
  @inlinable
  @inline(__always)
  static func ==(left: Self, right: Self) -> Bool {
    left.position == right.position
  }
}

extension _DequeSlot: Comparable {
  @inlinable
  @inline(__always)
  static func <(left: Self, right: Self) -> Bool {
    left.position < right.position
  }
}

extension Range where Bound == _DequeSlot {
  @inlinable
  @inline(__always)
  internal var _count: Int { upperBound.position - lowerBound.position }
}

extension Deque {
  @frozen
  @usableFromInline
  struct _Storage {
    @usableFromInline
    internal typealias _Buffer = ManagedBufferPointer<_DequeBufferHeader, Element>

    @usableFromInline
    internal var _buffer: _Buffer

    @inlinable
    @inline(__always)
    internal init(_buffer: _Buffer) {
      self._buffer = _buffer
    }
  }
}

extension Deque._Storage: CustomStringConvertible {
  @usableFromInline
  internal var description: String {
    "Deque<\(Element.self)>._Storage\(_buffer.header)"
  }
}

extension Deque._Storage {
  @inlinable
  internal init() {
    self.init(_buffer: _Buffer(unsafeBufferObject: _emptyDequeStorage))
  }

  @inlinable
  internal init(_ object: _DequeBuffer) {
    self.init(_buffer: _Buffer(unsafeBufferObject: object))
  }

  @inlinable
  internal init(minimumCapacity: Int) {
    let object = _DequeBuffer.create(
      minimumCapacity: minimumCapacity,
      makingHeaderWith: {
        #if os(OpenBSD)
        let capacity = minimumCapacity
        #else
        let capacity = $0.capacity
        #endif
        return _DequeBufferHeader(capacity: capacity, count: 0, startSlot: .zero)
      })
    self.init(_buffer: _Buffer(unsafeBufferObject: object))
  }
}

extension Deque._Storage {
  #if COLLECTIONS_INTERNAL_CHECKS
  @usableFromInline @inline(never) @_effects(releasenone)
  internal func _checkInvariants() {
    _buffer.withUnsafeMutablePointerToHeader { $0.pointee._checkInvariants() }
  }
  #else
  @inlinable @inline(__always)
  internal func _checkInvariants() {}
  #endif // COLLECTIONS_INTERNAL_CHECKS
}

extension Deque._Storage {
  @inlinable
  @inline(__always)
  internal var identity: AnyObject { _buffer.buffer }


  @inlinable
  @inline(__always)
  internal var capacity: Int {
    _buffer.withUnsafeMutablePointerToHeader { $0.pointee.capacity }
  }

  @inlinable
  @inline(__always)
  internal var count: Int {
    _buffer.withUnsafeMutablePointerToHeader { $0.pointee.count }
  }

  @inlinable
  @inline(__always)
  internal var startSlot: _DequeSlot {
    _buffer.withUnsafeMutablePointerToHeader { $0.pointee.startSlot
    }
  }
}

extension Deque._Storage {
  @usableFromInline
  internal typealias Index = Int

  @usableFromInline
  internal typealias _UnsafeHandle = Deque._UnsafeHandle

  @inlinable
  @inline(__always)
  internal func read(_ body: (_UnsafeHandle) throws -> R) rethrows -> R {
    try _buffer.withUnsafeMutablePointers { header, elements in
      let handle = _UnsafeHandle(header: header,
                                 elements: elements,
                                 isMutable: false)
      return try body(handle)
    }
  }

  @inlinable
  @inline(__always)
  internal func update(_ body: (_UnsafeHandle) throws -> R) rethrows -> R {
    try _buffer.withUnsafeMutablePointers { header, elements in
      let handle = _UnsafeHandle(header: header,
                                 elements: elements,
                                 isMutable: true)
      return try body(handle)
    }
  }
}

extension Deque._Storage {
  @inlinable
  @inline(__always)
  internal mutating func isUnique() -> Bool {
    _buffer.isUniqueReference()
  }

  @inlinable
  @inline(__always)
  internal mutating func ensureUnique() {
    if isUnique() { return }
    self._makeUniqueCopy()
  }

  @inlinable
  @inline(never)
  internal mutating func _makeUniqueCopy() {
    self = self.read { $0.copyElements() }
  }

  @inlinable
  @inline(__always)
  internal static var growthFactor: Double { 1.5 }

  @usableFromInline
  internal func _growCapacity(
    to minimumCapacity: Int,
    linearly: Bool
  ) -> Int {
    if linearly { return Swift.max(capacity, minimumCapacity) }
    return Swift.max(Int((Self.growthFactor * Double(capacity)).rounded(.up)),
                     minimumCapacity)
  }

  @inlinable
  @inline(__always)
  internal mutating func ensureUnique(
    minimumCapacity: Int,
    linearGrowth: Bool = false
  ) {
    let unique = isUnique()
    if _slowPath(capacity < minimumCapacity || !unique) {
      _ensureUnique(minimumCapacity: minimumCapacity, linearGrowth: linearGrowth)
    }
  }

  @inlinable
  internal mutating func _ensureUnique(
    minimumCapacity: Int,
    linearGrowth: Bool
  ) {
    if capacity >= minimumCapacity {
      assert(!self.isUnique())
      self = self.read { $0.copyElements() }
    } else if isUnique() {
      let minimumCapacity = _growCapacity(to: minimumCapacity, linearly: linearGrowth)
      self = self.update { source in
        source.moveElements(minimumCapacity: minimumCapacity)
      }
    } else {
      let minimumCapacity = _growCapacity(to: minimumCapacity, linearly: linearGrowth)
      self = self.read { source in
        source.copyElements(minimumCapacity: minimumCapacity)
      }
    }
  }
}

@usableFromInline
internal struct _DequeBufferHeader {
  @usableFromInline
  var capacity: Int

  @usableFromInline
  var count: Int

  @usableFromInline
  var startSlot: _DequeSlot

  @usableFromInline
  init(capacity: Int, count: Int, startSlot: _DequeSlot) {
    self.capacity = capacity
    self.count = count
    self.startSlot = startSlot
    _checkInvariants()
  }

  #if COLLECTIONS_INTERNAL_CHECKS
  @usableFromInline @inline(never) @_effects(releasenone)
  internal func _checkInvariants() {
    precondition(capacity >= 0)
    precondition(count >= 0 && count <= capacity)
    precondition(startSlot.position >= 0 && startSlot.position <= capacity)
  }
  #else
  @inlinable @inline(__always)
  internal func _checkInvariants() {}
  #endif
}

extension _DequeBufferHeader: CustomStringConvertible {
  @usableFromInline
  internal var description: String {
    "(capacity: \(capacity), count: \(count), startSlot: \(startSlot))"
  }
}

@_fixed_layout
@usableFromInline
internal class _DequeBuffer: ManagedBuffer<_DequeBufferHeader, Element> {
  @inlinable
  deinit {
    self.withUnsafeMutablePointers { header, elements in
      header.pointee._checkInvariants()

      let capacity = header.pointee.capacity
      let count = header.pointee.count
      let startSlot = header.pointee.startSlot

      if startSlot.position + count <= capacity {
        (elements + startSlot.position).deinitialize(count: count)
      } else {
        let firstRegion = capacity - startSlot.position
        (elements + startSlot.position).deinitialize(count: firstRegion)
        elements.deinitialize(count: count - firstRegion)
      }
    }
  }
}

extension _DequeBuffer: CustomStringConvertible {
  @usableFromInline
  internal var description: String {
    withUnsafeMutablePointerToHeader { "_DequeStorage<\(Element.self)>\($0.pointee)" }
  }
}

@usableFromInline
internal let _emptyDequeStorage = _DequeBuffer.create(
  minimumCapacity: 0,
  makingHeaderWith: { _ in
    _DequeBufferHeader(capacity: 0, count: 0, startSlot: .init(at: 0))
  })

extension Deque {
  @frozen
  @usableFromInline
  internal struct _UnsafeHandle {
    @usableFromInline
    let _header: UnsafeMutablePointer<_DequeBufferHeader>
    @usableFromInline
    let _elements: UnsafeMutablePointer
    #if DEBUG
    @usableFromInline
    let _isMutable: Bool
    #endif

    @inlinable
    @inline(__always)
    init(
      header: UnsafeMutablePointer<_DequeBufferHeader>,
      elements: UnsafeMutablePointer,
      isMutable: Bool
    ) {
      self._header = header
      self._elements = elements
      #if DEBUG
      self._isMutable = isMutable
      #endif
    }
  }
}

extension Deque._UnsafeHandle {
  @inlinable
  @inline(__always)
  func assertMutable() {
    #if DEBUG
    assert(_isMutable)
    #endif
  }
}

extension Deque._UnsafeHandle {
  @usableFromInline
  internal typealias Slot = _DequeSlot

  @inlinable
  @inline(__always)
  var header: _DequeBufferHeader {
    _header.pointee
  }

  @inlinable
  @inline(__always)
  var capacity: Int {
    _header.pointee.capacity
  }

  @inlinable
  @inline(__always)
  var count: Int {
    get { _header.pointee.count }
    nonmutating set { _header.pointee.count = newValue }
  }

  @inlinable
  @inline(__always)
  var startSlot: Slot {
    get { _header.pointee.startSlot }
    nonmutating set { _header.pointee.startSlot = newValue }
  }

  @inlinable
  @inline(__always)
  func ptr(at slot: Slot) -> UnsafeMutablePointer {
    assert(slot.position >= 0 && slot.position <= capacity)
    return _elements + slot.position
  }
}

extension Deque._UnsafeHandle {
  @inlinable
  @inline(__always)
  var mutableBuffer: UnsafeMutableBufferPointer {
    assertMutable()
    return .init(start: _elements, count: _header.pointee.capacity)
  }

  @inlinable
  internal func buffer(for range: Range) -> UnsafeBufferPointer {
    assert(range.upperBound.position <= capacity)
    return .init(start: _elements + range.lowerBound.position, count: range._count)
  }

  @inlinable
  @inline(__always)
  internal func mutableBuffer(for range: Range) -> UnsafeMutableBufferPointer {
    assertMutable()
    return .init(mutating: buffer(for: range))
  }
}

extension Deque._UnsafeHandle {
  @inlinable
  @inline(__always)
  internal var limSlot: Slot {
    Slot(at: capacity)
  }

  @inlinable
  internal func slot(after slot: Slot) -> Slot {
    assert(slot.position < capacity)
    let position = slot.position + 1
    if position >= capacity {
      return Slot(at: 0)
    }
    return Slot(at: position)
  }

  @inlinable
  internal func slot(before slot: Slot) -> Slot {
    assert(slot.position < capacity)
    if slot.position == 0 { return Slot(at: capacity - 1) }
    return Slot(at: slot.position - 1)
  }

  @inlinable
  internal func slot(_ slot: Slot, offsetBy delta: Int) -> Slot {
    assert(slot.position <= capacity)
    let position = slot.position + delta
    if delta >= 0 {
      if position >= capacity { return Slot(at: position - capacity) }
    } else {
      if position < 0 { return Slot(at: position + capacity) }
    }
    return Slot(at: position)
  }

  @inlinable
  @inline(__always)
  internal var endSlot: Slot {
    slot(startSlot, offsetBy: count)
  }

  /// Return the storage slot corresponding to the specified offset, which may
  /// or may not address an existing element.
  @inlinable
  internal func slot(forOffset offset: Int) -> Slot {
    assert(offset >= 0)
    assert(offset <= capacity) // Not `count`!
    // Note: The use of wrapping addition/subscription is justified here by the
    // fact that `offset` is guaranteed to fall in the range `0 ..< capacity`.
    // Eliminating the overflow checks leads to a measurable speedup for
    // random-access subscript operations. (Up to 2x on some microbenchmarks.)
    let position = startSlot.position &+ offset
    guard position < capacity else { return Slot(at: position &- capacity) }
    return Slot(at: position)
  }
}

extension Deque._UnsafeHandle {
  @inlinable
  internal func segments() -> _UnsafeWrappedBuffer {
    let wrap = capacity - startSlot.position
    if count <= wrap {
      return .init(start: ptr(at: startSlot), count: count)
    }
    return .init(first: ptr(at: startSlot), count: wrap,
                 second: ptr(at: .zero), count: count - wrap)
  }

  @inlinable
  internal func segments(
    forOffsets offsets: Range
  ) -> _UnsafeWrappedBuffer {
    assert(offsets.lowerBound >= 0 && offsets.upperBound <= count)
    let lower = slot(forOffset: offsets.lowerBound)
    let upper = slot(forOffset: offsets.upperBound)
    if offsets.count == 0 || lower < upper {
      return .init(start: ptr(at: lower), count: offsets.count)
    }
    return .init(first: ptr(at: lower), count: capacity - lower.position,
                 second: ptr(at: .zero), count: upper.position)
  }

  @inlinable
  @inline(__always)
  internal func mutableSegments() -> _UnsafeMutableWrappedBuffer {
    assertMutable()
    return .init(mutating: segments())
  }

  @inlinable
  @inline(__always)
  internal func mutableSegments(
    forOffsets range: Range
  ) -> _UnsafeMutableWrappedBuffer {
    assertMutable()
    return .init(mutating: segments(forOffsets: range))
  }
}

extension Deque._UnsafeHandle {
  @inlinable
  internal func availableSegments() -> _UnsafeMutableWrappedBuffer {
    assertMutable()
    let endSlot = self.endSlot
    guard count < capacity else { return .init(start: ptr(at: endSlot), count: 0) }
    if endSlot < startSlot { return .init(mutableBuffer(for: endSlot ..< startSlot)) }
    return .init(mutableBuffer(for: endSlot ..< limSlot),
                 mutableBuffer(for: .zero ..< startSlot))
  }
}

extension Deque._UnsafeHandle {
  @inlinable
  @discardableResult
  func initialize(
    at start: Slot,
    from source: UnsafeBufferPointer
  ) -> Slot {
    assert(start.position + source.count <= capacity)
    guard source.count > 0 else { return start }
    ptr(at: start).initialize(from: source.baseAddress!, count: source.count)
    return Slot(at: start.position + source.count)
  }

  @inlinable
  @inline(__always)
  @discardableResult
  func moveInitialize(
    at start: Slot,
    from source: UnsafeMutableBufferPointer
  ) -> Slot {
    assert(start.position + source.count <= capacity)
    guard source.count > 0 else { return start }
    ptr(at: start).moveInitialize(from: source.baseAddress!, count: source.count)
    return Slot(at: start.position + source.count)
  }

  @inlinable
  @inline(__always)
  @discardableResult
  public func move(
    from source: Slot,
    to target: Slot,
    count: Int
  ) -> (source: Slot, target: Slot) {
    assert(count >= 0)
    assert(source.position + count <= self.capacity)
    assert(target.position + count <= self.capacity)
    guard count > 0 else { return (source, target) }
    ptr(at: target).moveInitialize(from: ptr(at: source), count: count)
    return (slot(source, offsetBy: count), slot(target, offsetBy: count))
  }
}



extension Deque._UnsafeHandle {
  @inlinable
  internal func copyElements() -> Deque._Storage {
    let object = _DequeBuffer.create(
      minimumCapacity: capacity,
      makingHeaderWith: { _ in header })
    let result = Deque._Storage(_buffer: ManagedBufferPointer(unsafeBufferObject: object))
    guard self.count > 0 else { return result }
    result.update { target in
      let source = self.segments()
      target.initialize(at: startSlot, from: source.first)
      if let second = source.second {
        target.initialize(at: .zero, from: second)
      }
    }
    return result
  }

  @inlinable
  internal func copyElements(minimumCapacity: Int) -> Deque._Storage {
    assert(minimumCapacity >= count)
    let object = _DequeBuffer.create(
      minimumCapacity: minimumCapacity,
      makingHeaderWith: {
        #if os(OpenBSD)
        let capacity = minimumCapacity
        #else
        let capacity = $0.capacity
        #endif
        return _DequeBufferHeader(
          capacity: capacity,
          count: count,
          startSlot: .zero)
      })
    let result = Deque._Storage(_buffer: ManagedBufferPointer(unsafeBufferObject: object))
    guard count > 0 else { return result }
    result.update { target in
      assert(target.count == count && target.startSlot.position == 0)
      let source = self.segments()
      let next = target.initialize(at: .zero, from: source.first)
      if let second = source.second {
        target.initialize(at: next, from: second)
      }
    }
    return result
  }

  @inlinable
  internal func moveElements(minimumCapacity: Int) -> Deque._Storage {
    assertMutable()
    let count = self.count
    assert(minimumCapacity >= count)
    let object = _DequeBuffer.create(
      minimumCapacity: minimumCapacity,
      makingHeaderWith: {
        #if os(OpenBSD)
        let capacity = minimumCapacity
        #else
        let capacity = $0.capacity
        #endif
        return _DequeBufferHeader(
          capacity: capacity,
          count: count,
          startSlot: .zero)
      })
    let result = Deque._Storage(_buffer: ManagedBufferPointer(unsafeBufferObject: object))
    guard count > 0 else { return result }
    result.update { target in
      let source = self.mutableSegments()
      let next = target.moveInitialize(at: .zero, from: source.first)
      if let second = source.second {
        target.moveInitialize(at: next, from: second)
      }
    }
    self.count = 0
    return result
  }
}

extension Deque._UnsafeHandle {
  @inlinable
  internal func withUnsafeSegment(
    startingAt start: Int,
    maximumCount: Int?,
    _ body: (UnsafeBufferPointer) throws -> R
  ) rethrows -> (end: Int, result: R) {
    assert(start <= count)
    guard start < count else {
      return try (count, body(UnsafeBufferPointer(start: nil, count: 0)))
    }
    let endSlot = self.endSlot

    let segmentStart = self.slot(forOffset: start)
    let segmentEnd = segmentStart < endSlot ? endSlot : limSlot
    let count = Swift.min(maximumCount ?? Int.max, segmentEnd.position - segmentStart.position)
    let result = try body(UnsafeBufferPointer(start: ptr(at: segmentStart), count: count))
    return (start + count, result)
  }
}

extension Deque._UnsafeHandle {
  @inlinable
  internal func uncheckedReplaceInPlace(
    inOffsets range: Range,
    with newElements: C
  ) where C.Element == Element {
    assertMutable()
    assert(range.upperBound <= count)
    assert(newElements.count == range.count)
    guard !range.isEmpty else { return }
    let target = mutableSegments(forOffsets: range)
    target.assign(from: newElements)
  }
}

// MARK: Appending
extension Deque._UnsafeHandle {
  @inlinable
  internal func uncheckedAppend(_ element: Element) {
    assertMutable()
    assert(count < capacity)
    ptr(at: endSlot).initialize(to: element)
    count += 1
  }

  @inlinable
  internal func uncheckedAppend(contentsOf source: UnsafeBufferPointer) {
    assertMutable()
    assert(count + source.count <= capacity)
    guard source.count > 0 else { return }
    let c = self.count
    count += source.count
    let gap = mutableSegments(forOffsets: c ..< count)
    gap.initialize(from: source)
  }
}

extension Deque._UnsafeHandle {
  @inlinable
  internal func uncheckedPrepend(_ element: Element) {
    assertMutable()
    assert(count < capacity)
    let slot = self.slot(before: startSlot)
    ptr(at: slot).initialize(to: element)
    startSlot = slot
    count += 1
  }

  @inlinable
  internal func uncheckedPrepend(contentsOf source: UnsafeBufferPointer) {
    assertMutable()
    assert(count + source.count <= capacity)
    guard source.count > 0 else { return }
    let oldStart = startSlot
    let newStart = self.slot(startSlot, offsetBy: -source.count)
    startSlot = newStart
    count += source.count

    let gap = mutableWrappedBuffer(between: newStart, and: oldStart)
    gap.initialize(from: source)
  }
}

extension Deque._UnsafeHandle {
  @inlinable
  internal func uncheckedInsert(
    contentsOf newElements: __owned C,
    count newCount: Int,
    atOffset offset: Int
  ) where C.Element == Element {
    assertMutable()
    assert(offset <= count)
    assert(newElements.count == newCount)
    guard newCount > 0 else { return }
    let gap = openGap(ofSize: newCount, atOffset: offset)
    gap.initialize(from: newElements)
  }

  @inlinable
  internal func mutableWrappedBuffer(
    between start: Slot,
    and end: Slot
  ) -> _UnsafeMutableWrappedBuffer {
    assert(start.position <= capacity)
    assert(end.position <= capacity)
    if start < end {
      return .init(start: ptr(at: start), count: end.position - start.position)
    }
    return .init(
      first: ptr(at: start), count: capacity - start.position,
      second: ptr(at: .zero), count: end.position)
  }

  @inlinable
  internal func openGap(
    ofSize gapSize: Int,
    atOffset offset: Int
  ) -> _UnsafeMutableWrappedBuffer {
    assertMutable()
    assert(offset >= 0 && offset <= self.count)
    assert(self.count + gapSize <= capacity)
    assert(gapSize > 0)

    let headCount = offset
    let tailCount = count - offset
    if tailCount <= headCount {

      let originalEnd = self.slot(startSlot, offsetBy: count)
      let newEnd = self.slot(startSlot, offsetBy: count + gapSize)
      let gapStart = self.slot(forOffset: offset)
      let gapEnd = self.slot(gapStart, offsetBy: gapSize)

      let sourceIsContiguous = gapStart <= originalEnd.orIfZero(capacity)
      let targetIsContiguous = gapEnd <= newEnd.orIfZero(capacity)

      if sourceIsContiguous && targetIsContiguous {
        move(from: gapStart, to: gapEnd, count: tailCount)
      } else if targetIsContiguous {
        assert(startSlot > originalEnd.orIfZero(capacity))
        move(from: .zero, to: Slot.zero.advanced(by: gapSize), count: originalEnd.position)
        move(from: gapStart, to: gapEnd, count: capacity - gapStart.position)
      } else if sourceIsContiguous {
        move(from: limSlot.advanced(by: -gapSize), to: .zero, count: newEnd.position)
        move(from: gapStart, to: gapEnd, count: tailCount - newEnd.position)
      } else {
        move(from: .zero, to: Slot.zero.advanced(by: gapSize), count: originalEnd.position)
        move(from: limSlot.advanced(by: -gapSize), to: .zero, count: gapSize)
        move(from: gapStart, to: gapEnd, count: tailCount - gapSize - originalEnd.position)
      }
      count += gapSize
      return mutableWrappedBuffer(between: gapStart, and: gapEnd.orIfZero(capacity))
    }

    let originalStart = self.startSlot
    let newStart = self.slot(originalStart, offsetBy: -gapSize)
    let gapEnd = self.slot(forOffset: offset)
    let gapStart = self.slot(gapEnd, offsetBy: -gapSize)

    let sourceIsContiguous = originalStart <= gapEnd.orIfZero(capacity)
    let targetIsContiguous = newStart <= gapStart.orIfZero(capacity)

    if sourceIsContiguous && targetIsContiguous {
      move(from: originalStart, to: newStart, count: headCount)
    } else if targetIsContiguous {
      assert(originalStart >= newStart)
      move(from: originalStart, to: newStart, count: capacity - originalStart.position)
      move(from: .zero, to: limSlot.advanced(by: -gapSize), count: gapEnd.position)
    } else if sourceIsContiguous {
      move(from: originalStart, to: newStart, count: capacity - newStart.position)
      move(from: Slot.zero.advanced(by: gapSize), to: .zero, count: gapStart.position)
    } else {
      move(from: originalStart, to: newStart, count: capacity - originalStart.position)
      move(from: .zero, to: limSlot.advanced(by: -gapSize), count: gapSize)
      move(from: Slot.zero.advanced(by: gapSize), to: .zero, count: gapStart.position)
    }
    startSlot = newStart
    count += gapSize
    return mutableWrappedBuffer(between: gapStart, and: gapEnd.orIfZero(capacity))
  }
}

extension Deque._UnsafeHandle {
  @inlinable
  internal func uncheckedRemoveFirst() -> Element {
    assertMutable()
    assert(count > 0)
    let result = ptr(at: startSlot).move()
    startSlot = slot(after: startSlot)
    count -= 1
    return result
  }

  @inlinable
  internal func uncheckedRemoveLast() -> Element {
    assertMutable()
    assert(count > 0)
    let slot = self.slot(forOffset: count - 1)
    let result = ptr(at: slot).move()
    count -= 1
    return result
  }

  @inlinable
  internal func uncheckedRemoveFirst(_ n: Int) {
    assertMutable()
    assert(count >= n)
    guard n > 0 else { return }
    let target = mutableSegments(forOffsets: 0 ..< n)
    target.deinitialize()
    startSlot = slot(startSlot, offsetBy: n)
    count -= n
  }

  @inlinable
  internal func uncheckedRemoveLast(_ n: Int) {
    assertMutable()
    assert(count >= n)
    guard n > 0 else { return }
    let target = mutableSegments(forOffsets: count - n ..< count)
    target.deinitialize()
    count -= n
  }

  @inlinable
  internal func uncheckedRemoveAll() {
    assertMutable()
    guard count > 0 else { return }
    let target = mutableSegments()
    target.deinitialize()
    count = 0
    startSlot = .zero
  }

  @inlinable
  internal func uncheckedRemove(offsets bounds: Range) {
    assertMutable()
    assert(bounds.lowerBound >= 0 && bounds.upperBound <= self.count)

    mutableSegments(forOffsets: bounds).deinitialize()
    closeGap(offsets: bounds)
  }

  @inlinable
  internal func closeGap(offsets bounds: Range) {
    assertMutable()
    assert(bounds.lowerBound >= 0 && bounds.upperBound <= self.count)
    let gapSize = bounds.count
    guard gapSize > 0 else { return }

    let gapStart = self.slot(forOffset: bounds.lowerBound)
    let gapEnd = self.slot(forOffset: bounds.upperBound)

    let headCount = bounds.lowerBound
    let tailCount = count - bounds.upperBound

    if headCount >= tailCount {
      let originalEnd = endSlot
      let newEnd = self.slot(forOffset: count - gapSize)

      let sourceIsContiguous = gapEnd < originalEnd.orIfZero(capacity)
      let targetIsContiguous = gapStart <= newEnd.orIfZero(capacity)
      if tailCount == 0 {
      } else if sourceIsContiguous && targetIsContiguous {
        move(from: gapEnd, to: gapStart, count: tailCount)
      } else if sourceIsContiguous {
        let c = capacity - gapStart.position
        assert(tailCount > c)
        let next = move(from: gapEnd, to: gapStart, count: c)
        move(from: next.source, to: .zero, count: tailCount - c)
      } else if targetIsContiguous {
        let next = move(from: gapEnd, to: gapStart, count: capacity - gapEnd.position)
        move(from: .zero, to: next.target, count: originalEnd.position)
      } else {
        var next = move(from: gapEnd, to: gapStart, count: capacity - gapEnd.position)
        next = move(from: .zero, to: next.target, count: gapSize)
        move(from: next.source, to: .zero, count: newEnd.position)
      }
      count -= gapSize
    } else {
      let originalStart = startSlot
      let newStart = slot(startSlot, offsetBy: gapSize)

      let sourceIsContiguous = originalStart < gapStart.orIfZero(capacity)
      let targetIsContiguous = newStart <= gapEnd.orIfZero(capacity)

      if headCount == 0 {
      } else if sourceIsContiguous && targetIsContiguous {
        move(from: originalStart, to: newStart, count: headCount)
      } else if sourceIsContiguous {
        move(from: limSlot.advanced(by: -gapSize), to: .zero, count: gapEnd.position)
        move(from: startSlot, to: newStart, count: headCount - gapEnd.position)
      } else if targetIsContiguous {
        move(from: .zero, to: gapEnd.advanced(by: -gapStart.position), count: gapStart.position)
        move(from: startSlot, to: newStart, count: headCount - gapStart.position)
      } else {
        move(from: .zero, to: Slot.zero.advanced(by: gapSize), count: gapStart.position)
        move(from: limSlot.advanced(by: -gapSize), to: .zero, count: gapSize)
        move(from: startSlot, to: newStart, count: headCount - gapEnd.position)
      }
      startSlot = newStart
      count -= gapSize
    }
  }
}

@frozen
@usableFromInline
internal struct _UnsafeWrappedBuffer {
  @usableFromInline
  internal let first: UnsafeBufferPointer

  @usableFromInline
  internal let second: UnsafeBufferPointer?

  @inlinable
  @inline(__always)
  internal init(
    _ first: UnsafeBufferPointer,
    _ second: UnsafeBufferPointer? = nil
  ) {
    self.first = first
    self.second = second
    assert(first.count > 0 || second == nil)
  }

  @inlinable
  internal init(
    start: UnsafePointer,
    count: Int
  ) {
    self.init(UnsafeBufferPointer(start: start, count: count))
  }

  @inlinable
  internal init(
    first start1: UnsafePointer,
    count count1: Int,
    second start2: UnsafePointer,
    count count2: Int
  ) {
    self.init(UnsafeBufferPointer(start: start1, count: count1),
              UnsafeBufferPointer(start: start2, count: count2))
  }

  @inlinable
  internal var count: Int { first.count + (second?.count ?? 0) }
}

@frozen
@usableFromInline
internal struct _UnsafeMutableWrappedBuffer {
  @usableFromInline
  internal let first: UnsafeMutableBufferPointer

  @usableFromInline
  internal let second: UnsafeMutableBufferPointer?

  @inlinable
  @inline(__always)
  internal init(
    _ first: UnsafeMutableBufferPointer,
    _ second: UnsafeMutableBufferPointer? = nil
  ) {
    self.first = first
    self.second = second?.count == 0 ? nil : second
    assert(first.count > 0 || second == nil)
  }

  @inlinable
  @inline(__always)
  internal init(
    _ first: UnsafeMutableBufferPointer.SubSequence,
    _ second: UnsafeMutableBufferPointer? = nil
  ) {
    self.init(UnsafeMutableBufferPointer(rebasing: first), second)
  }

  @inlinable
  @inline(__always)
  internal init(
    _ first: UnsafeMutableBufferPointer,
    _ second: UnsafeMutableBufferPointer.SubSequence
  ) {
    self.init(first, UnsafeMutableBufferPointer(rebasing: second))
  }

  @inlinable
  @inline(__always)
  internal init(
    start: UnsafeMutablePointer,
    count: Int
  ) {
    self.init(UnsafeMutableBufferPointer(start: start, count: count))
  }

  @inlinable
  @inline(__always)
  internal init(
    first start1: UnsafeMutablePointer,
    count count1: Int,
    second start2: UnsafeMutablePointer,
    count count2: Int
  ) {
    self.init(UnsafeMutableBufferPointer(start: start1, count: count1),
              UnsafeMutableBufferPointer(start: start2, count: count2))
  }

  @inlinable
  @inline(__always)
  internal init(mutating buffer: _UnsafeWrappedBuffer) {
    self.init(.init(mutating: buffer.first),
              buffer.second.map { .init(mutating: $0) })
  }
}

extension _UnsafeMutableWrappedBuffer {
  @inlinable
  @inline(__always)
  internal var count: Int { first.count + (second?.count ?? 0) }

  @inlinable
  internal func prefix(_ n: Int) -> Self {
    assert(n >= 0)
    if n >= self.count {
      return self
    }
    if n <= first.count {
      return Self(first.prefix(n))
    }
    return Self(first, second!.prefix(n - first.count))
  }

  @inlinable
  internal func suffix(_ n: Int) -> Self {
    assert(n >= 0)
    if n >= self.count {
      return self
    }
    guard let second = second else {
      return Self(first.suffix(n))
    }
    if n <= second.count {
      return Self(second.suffix(n))
    }
    return Self(first.suffix(n - second.count), second)
  }
}

extension _UnsafeMutableWrappedBuffer {
  @inlinable
  internal func deinitialize() {
    first.deinitialize()
    second?.deinitialize()
  }

  @inlinable
  @discardableResult
  internal func initialize(
    fromPrefixOf iterator: inout I
  ) -> Int
  where I.Element == Element {
    var copied = 0
    var gap = first
    var wrapped = false
    while true {
      if copied == gap.count {
        guard !wrapped, let second = second, second.count > 0 else { break }
        gap = second
        copied = 0
        wrapped = true
      }
      guard let next = iterator.next() else { break }
      (gap.baseAddress! + copied).initialize(to: next)
      copied += 1
    }
    return wrapped ? first.count + copied : copied
  }

  @inlinable
  internal func initialize(
    fromSequencePrefix elements: __owned S
  ) -> (iterator: S.Iterator, count: Int)
  where S.Element == Element {
    guard second == nil || first.count >= elements.underestimatedCount else {
      var it = elements.makeIterator()
      let copied = initialize(fromPrefixOf: &it)
      return (it, copied)
    }
    var (it, copied) = elements._copyContents(initializing: first)
    if copied == first.count, let second = second {
      var i = 0
      while i < second.count {
        guard let next = it.next() else { break }
        (second.baseAddress! + i).initialize(to: next)
        i += 1
      }
      copied += i
    }
    return (it, copied)
  }

  @inlinable
  internal func initialize(
    from elements: __owned C
  ) where C.Element == Element {
    assert(self.count == elements.count)
    if let second = second {
      let wrap = elements.index(elements.startIndex, offsetBy: first.count)
      first.initializeAll(fromContentsOf: elements[..(
    from elements: C
  ) where C.Element == Element {
    assert(elements.count == self.count)
    deinitialize()
    initialize(from: elements)
  }
}

extension UnsafeMutableBufferPointer {
  @discardableResult
  @inlinable
  public func deinitialize() -> UnsafeMutableRawBufferPointer {
    guard let start = baseAddress else { return .init(start: nil, count: 0) }
    start.deinitialize(count: count)
    return .init(start: UnsafeMutableRawPointer(start),
                 count: count * MemoryLayout.stride)
  }
}

extension UnsafeMutableBufferPointer {
  @inlinable
  public func initialize(
    fromContentsOf source: C
  ) -> Index
  where C.Element == Element {
    let count: Int? = source._withContiguousStorageIfAvailable_SR14663 {
      guard let sourceAddress = $0.baseAddress, !$0.isEmpty else {
        return 0
      }
      precondition(
        $0.count <= self.count,
        "buffer cannot contain every element from source."
      )
      baseAddress?.initialize(from: sourceAddress, count: $0.count)
      return $0.count
    }
    if let count = count {
      return startIndex.advanced(by: count)
    }

    var (iterator, copied) = source._copyContents(initializing: self)
    precondition(
      iterator.next() == nil,
      "buffer cannot contain every element from source."
    )
    return startIndex.advanced(by: copied)
  }

  @inlinable
  @_alwaysEmitIntoClient
  public func moveInitialize(fromContentsOf source: Self) -> Index {
    guard let sourceAddress = source.baseAddress, !source.isEmpty else {
      return startIndex
    }
    precondition(
      source.count <= self.count,
      "buffer cannot contain every element from source."
    )
    baseAddress?.moveInitialize(from: sourceAddress, count: source.count)
    return startIndex.advanced(by: source.count)
  }

  @inlinable
  @_alwaysEmitIntoClient
  public func moveInitialize(fromContentsOf source: Slice) -> Index {
    return moveInitialize(fromContentsOf: Self(rebasing: source))
  }

  @inlinable
  @_alwaysEmitIntoClient
  public func initializeElement(at index: Index, to value: Element) {
    assert(startIndex <= index && index < endIndex)
    let p = baseAddress.unsafelyUnwrapped.advanced(by: index)
    p.initialize(to: value)
  }

  @inlinable
  @_alwaysEmitIntoClient
  public func moveElement(from index: Index) -> Element {
    assert(startIndex <= index && index < endIndex)
    return baseAddress.unsafelyUnwrapped.advanced(by: index).move()
  }

  @inlinable
  @_alwaysEmitIntoClient
  public func deinitializeElement(at index: Index) {
    assert(startIndex <= index && index < endIndex)
    let p = baseAddress.unsafelyUnwrapped.advanced(by: index)
    p.deinitialize(count: 1)
  }
}

extension Slice {
  @inlinable
  @_alwaysEmitIntoClient
  public func initialize(
    fromContentsOf source: C
  ) -> Index where Base == UnsafeMutableBufferPointer {
    let buffer = Base(rebasing: self)
    let index = buffer.initialize(fromContentsOf: source)
    let distance = buffer.distance(from: buffer.startIndex, to: index)
    return startIndex.advanced(by: distance)
  }
  
  @inlinable
  @_alwaysEmitIntoClient
  public func moveInitialize(
    fromContentsOf source: UnsafeMutableBufferPointer
  ) -> Index where Base == UnsafeMutableBufferPointer {
    let buffer = Base(rebasing: self)
    let index = buffer.moveInitialize(fromContentsOf: source)
    let distance = buffer.distance(from: buffer.startIndex, to: index)
    return startIndex.advanced(by: distance)
  }

  @inlinable
  @_alwaysEmitIntoClient
  public func moveInitialize(
    fromContentsOf source: Slice>
  ) -> Index where Base == UnsafeMutableBufferPointer {
    let buffer = Base(rebasing: self)
    let index = buffer.moveInitialize(fromContentsOf: source)
    let distance = buffer.distance(from: buffer.startIndex, to: index)
    return startIndex.advanced(by: distance)
  }

  @discardableResult
  @inlinable
  @_alwaysEmitIntoClient
  public func deinitialize() -> UnsafeMutableRawBufferPointer
  where Base == UnsafeMutableBufferPointer {
    Base(rebasing: self).deinitialize()
  }

  @inlinable
  @_alwaysEmitIntoClient
  public func initializeElement(at index: Int, to value: Element)
  where Base == UnsafeMutableBufferPointer {
    assert(startIndex <= index && index < endIndex)
    base.baseAddress.unsafelyUnwrapped.advanced(by: index).initialize(to: value)
  }
}

#if swift(<5.8)
extension UnsafeMutableBufferPointer {
  @_alwaysEmitIntoClient
  public func update(repeating repeatedValue: Element) {
    guard let dstBase = baseAddress else { return }
    dstBase.update(repeating: repeatedValue, count: count)
  }
}
#endif

#if swift(<5.8)
extension Slice {
  @_alwaysEmitIntoClient
  public func update(repeating repeatedValue: Element)
  where Base == UnsafeMutableBufferPointer {
    Base(rebasing: self).update(repeating: repeatedValue)
  }
}
#endif

extension UnsafeMutableBufferPointer {
  @inlinable
  public func initialize(fromContentsOf source: Self) -> Index {
    guard source.count > 0 else { return 0 }
    precondition(
      source.count <= self.count,
      "buffer cannot contain every element from source.")
    baseAddress.unsafelyUnwrapped.initialize(
      from: source.baseAddress.unsafelyUnwrapped,
      count: source.count)
    return source.count
  }

  @inlinable
  public func initialize(fromContentsOf source: Slice) -> Index {
    let sourceCount = source.count
    guard sourceCount > 0 else { return 0 }
    precondition(
      sourceCount <= self.count,
      "buffer cannot contain every element from source.")
    baseAddress.unsafelyUnwrapped.initialize(
      from: source.base.baseAddress.unsafelyUnwrapped + source.startIndex,
      count: sourceCount)
    return sourceCount
  }
}

extension Slice {
  @inlinable @inline(__always)
  public func initialize(
    fromContentsOf source: UnsafeMutableBufferPointer
  ) -> Index
  where Base == UnsafeMutableBufferPointer
  {
    let target = UnsafeMutableBufferPointer(rebasing: self)
    let i = target.initialize(fromContentsOf: source)
    return self.startIndex + i
  }

  @inlinable @inline(__always)
  public func initialize(
    fromContentsOf source: Slice>
  ) -> Index
  where Base == UnsafeMutableBufferPointer
  {
    let target = UnsafeMutableBufferPointer(rebasing: self)
    let i = target.initialize(fromContentsOf: source)
    return self.startIndex + i
  }
}

extension UnsafeMutableBufferPointer {
  @inlinable @inline(__always)
  public func initializeAll(
    fromContentsOf source: C
  ) where C.Element == Element {
    let i = self.initialize(fromContentsOf: source)
    assert(i == self.endIndex)
  }

  @inlinable @inline(__always)
  public func initializeAll(fromContentsOf source: Self) {
    let i = self.initialize(fromContentsOf: source)
    assert(i == self.endIndex)
  }

  @inlinable @inline(__always)
  public func initializeAll(fromContentsOf source: Slice) {
    let i = self.initialize(fromContentsOf: source)
    assert(i == self.endIndex)
  }

  @inlinable @inline(__always)
  public func moveInitializeAll(fromContentsOf source: Self) {
    let i = self.moveInitialize(fromContentsOf: source)
    assert(i == self.endIndex)
  }

  @inlinable @inline(__always)
  public func moveInitializeAll(fromContentsOf source: Slice) {
    let i = self.moveInitialize(fromContentsOf: source)
    assert(i == self.endIndex)
  }
}

extension Slice {
  @inlinable @inline(__always)
  public func initializeAll(
    fromContentsOf source: C
  ) where Base == UnsafeMutableBufferPointer {
    let i = self.initialize(fromContentsOf: source)
    assert(i == self.endIndex)
  }

  @inlinable @inline(__always)
  public func initializeAll(
    fromContentsOf source: UnsafeMutableBufferPointer
  ) where Base == UnsafeMutableBufferPointer {
    let target = UnsafeMutableBufferPointer(rebasing: self)
    target.initializeAll(fromContentsOf: source)
  }

  @inlinable @inline(__always)
  public func initializeAll(
    fromContentsOf source: Slice>
  ) where Base == UnsafeMutableBufferPointer {
    let target = UnsafeMutableBufferPointer(rebasing: self)
    target.initializeAll(fromContentsOf: source)
  }

  @inlinable @inline(__always)
  public func moveInitializeAll(
    fromContentsOf source: UnsafeMutableBufferPointer
  ) where Base == UnsafeMutableBufferPointer {
    let target = UnsafeMutableBufferPointer(rebasing: self)
    target.moveInitializeAll(fromContentsOf: source)
  }

  @inlinable @inline(__always)
  public func moveInitializeAll(
    fromContentsOf source: Slice>
  ) where Base == UnsafeMutableBufferPointer {
    let target = UnsafeMutableBufferPointer(rebasing: self)
    target.moveInitializeAll(fromContentsOf: source)
  }
}

#if swift(<5.8)
extension UnsafeMutablePointer {
  @_alwaysEmitIntoClient
  public func update(repeating repeatedValue: Pointee, count: Int) {
    assert(count >= 0, "UnsafeMutablePointer.update(repeating:count:) with negative count")
    for i in 0 ..< count {
      self[i] = repeatedValue
    }
  }
}
#endif

extension Array {
  @inlinable
  internal static func _isWCSIABroken() -> Bool {
    #if _runtime(_ObjC)
    guard _isBridgedVerbatimToObjectiveC(Element.self) else {
      return false
    }
    #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
    if #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) {
      return false
    }
    return true
    #else
    return false
    #endif

    #else
    return false
    #endif
  }
}

extension Sequence {
  @inlinable @inline(__always)
  public func _withContiguousStorageIfAvailable_SR14663(
    _ body: (UnsafeBufferPointer) throws -> R
  ) rethrows -> R? {
    if Self.self == Array.self && Array._isWCSIABroken() {
      return nil
    }

    return try self.withContiguousStorageIfAvailable(body)
  }
}

extension Deque: Hashable where Element: Hashable {
  @inlinable
  public func hash(into hasher: inout Hasher) {
    hasher.combine(count) // discriminator
    for element in self {
      hasher.combine(element)
    }
  }
}

extension Deque: Sequence {
  @frozen
  public struct Iterator: IteratorProtocol {
    @usableFromInline
    internal var _storage: Deque._Storage

    @usableFromInline
    internal var _nextSlot: _Slot

    @usableFromInline
    internal var _endSlot: _Slot

    @inlinable
    internal init(_storage: Deque._Storage, start: _Slot, end: _Slot) {
      self._storage = _storage
      self._nextSlot = start
      self._endSlot = end
    }

    @inlinable
    internal init(_base: Deque) {
      self = _base._storage.read { handle in
        let start = handle.startSlot
        let end = Swift.min(start.advanced(by: handle.count), handle.limSlot)
        return Self(_storage: _base._storage, start: start, end: end)
      }
    }

    @inlinable
    internal init(_base: Deque, from index: Int) {
      self = _base._storage.read { handle in
        assert(index >= 0 && index <= handle.count)
        let start = handle.slot(forOffset: index)
        if index == handle.count {
          return Self(_storage: _base._storage, start: start, end: start)
        }
        var end = handle.endSlot
        if start >= end { end = handle.limSlot }
        return Self(_storage: _base._storage, start: start, end: end)
      }
    }

    @inlinable
    @inline(never)
    internal mutating func _swapSegment() -> Bool {
      assert(_nextSlot == _endSlot)
      return _storage.read { handle in
        let end = handle.endSlot
        if end == .zero || end == _nextSlot {
          return false
        }
        _endSlot = end
        _nextSlot = .zero
        return true
      }
    }

    @inlinable
    public mutating func next() -> Element? {
      if _nextSlot == _endSlot {
        guard _swapSegment() else { return nil }
      }
      assert(_nextSlot < _endSlot)
      let slot = _nextSlot
      _nextSlot = _nextSlot.advanced(by: 1)
      return _storage.read { handle in
        return handle.ptr(at: slot).pointee
      }
    }
  }

  @inlinable
  public func makeIterator() -> Iterator {
    Iterator(_base: self)
  }

  @inlinable
  public __consuming func _copyToContiguousArray() -> ContiguousArray {
    ContiguousArray(unsafeUninitializedCapacity: _storage.count) { target, count in
      _storage.read { source in
        let segments = source.segments()
        let c = segments.first.count
        target[..
  ) -> (Iterator, UnsafeMutableBufferPointer.Index) {
    _storage.read { source in
      let segments = source.segments()
      let c1 = Swift.min(segments.first.count, target.count)
      target[.. c1, let second = segments.second else {
        return (Iterator(_base: self, from: c1), c1)
      }
      let c2 = Swift.min(second.count, target.count - c1)
      target[c1 ..< c1 + c2].initializeAll(fromContentsOf: second.prefix(c2))
      return (Iterator(_base: self, from: c1 + c2), c1 + c2)
    }
  }

  @inlinable
  public func withContiguousStorageIfAvailable(
    _ body: (UnsafeBufferPointer) throws -> R
  ) rethrows -> R? {
    return try _storage.read { handle in
      let endSlot = handle.startSlot.advanced(by: handle.count)
      guard endSlot.position <= handle.capacity else { return nil }
      return try body(handle.buffer(for: handle.startSlot ..< endSlot))
    }
  }
}

#if swift(>=5.5)
extension Deque.Iterator: Sendable where Element: Sendable {}
#endif

extension Deque: RandomAccessCollection {
  public typealias Index = Int
  public typealias SubSequence = Slice
  public typealias Indices = Range

  @inlinable
  @inline(__always)
  public var count: Int { _storage.count }

  @inlinable
  @inline(__always)
  public var startIndex: Int { 0 }

  @inlinable
  @inline(__always)
  public var endIndex: Int { count }

  @inlinable
  @inline(__always)
  public var indices: Range { 0 ..< count }

  @inlinable
  @inline(__always)
  public func index(after i: Int) -> Int {
    return i + 1
  }

  @inlinable
  @inline(__always)
  public func formIndex(after i: inout Int) {
    i += 1
  }

  @inlinable
  @inline(__always)
  public func index(before i: Int) -> Int {
    return i - 1
  }

  @inlinable
  @inline(__always)
  public func formIndex(before i: inout Int) {
    i -= 1
  }

  @inlinable
  @inline(__always)
  public func index(_ i: Int, offsetBy distance: Int) -> Int {
    return i + distance
  }

  @inlinable
  public func index(
    _ i: Int,
    offsetBy distance: Int,
    limitedBy limit: Int
  ) -> Int? {
    let l = limit - i
    if distance > 0 ? l >= 0 && l < distance : l <= 0 && distance < l {
      return nil
    }
    return i + distance
  }

  @inlinable
  @inline(__always)
  public func distance(from start: Int, to end: Int) -> Int {
    return end - start
  }

  @inlinable
  public subscript(index: Int) -> Element {
    get {
      precondition(index >= 0 && index < count, "Index out of bounds")
      return _storage.read { $0.ptr(at: $0.slot(forOffset: index)).pointee }
    }
    set {
      precondition(index >= 0 && index < count, "Index out of bounds")
      _storage.ensureUnique()
      _storage.update { handle in
        let slot = handle.slot(forOffset: index)
        handle.ptr(at: slot).pointee = newValue
      }
    }
    @inline(__always)
    _modify {
      precondition(index >= 0 && index < count, "Index out of bounds")
      var (slot, value) = _prepareForModify(at: index)
      defer {
        _finalizeModify(slot, value)
      }
      yield &value
    }
  }

  @inlinable
  internal mutating func _prepareForModify(at index: Int) -> (_Slot, Element) {
    _storage.ensureUnique()
    return _storage.update { handle in
      let slot = handle.slot(forOffset: index)
      return (slot, handle.ptr(at: slot).move())
    }
  }

  @inlinable
  internal mutating func _finalizeModify(_ slot: _Slot, _ value: Element) {
    _storage.update { handle in
      handle.ptr(at: slot).initialize(to: value)
    }
  }

  @inlinable
  public subscript(bounds: Range) -> Slice {
    get {
      precondition(bounds.lowerBound >= 0 && bounds.upperBound <= count,
                   "Invalid bounds")
      return Slice(base: self, bounds: bounds)
    }
    set(source) {
      precondition(bounds.lowerBound >= 0 && bounds.upperBound <= count,
                   "Invalid bounds")
      self.replaceSubrange(bounds, with: source)
    }
  }
}

extension Deque: MutableCollection {
  @inlinable
  public mutating func swapAt(_ i: Int, _ j: Int) {
    precondition(i >= 0 && i < count, "Index out of bounds")
    precondition(j >= 0 && j < count, "Index out of bounds")
    _storage.ensureUnique()
    _storage.update { handle in
      let slot1 = handle.slot(forOffset: i)
      let slot2 = handle.slot(forOffset: j)
      handle.mutableBuffer.swapAt(slot1.position, slot2.position)
    }
  }

  @inlinable
  public mutating func withContiguousMutableStorageIfAvailable(
    _ body: (inout UnsafeMutableBufferPointer) throws -> R
  ) rethrows -> R? {
    _storage.ensureUnique()
    return try _storage.update { handle in
      let endSlot = handle.startSlot.advanced(by: handle.count)
      guard endSlot.position <= handle.capacity else {
        return nil
      }
      let original = handle.mutableBuffer(for: handle.startSlot ..< endSlot)
      var extract = original
      defer {
        precondition(extract.baseAddress == original.baseAddress && extract.count == original.count,
                     "Closure must not replace the provided buffer")
      }
      return try body(&extract)
    }
  }

  @inlinable
  public mutating func _withUnsafeMutableBufferPointerIfSupported(
    _ body: (inout UnsafeMutableBufferPointer) throws -> R
  ) rethrows -> R? {
    return try withContiguousMutableStorageIfAvailable(body)
  }
}

extension Deque: RangeReplaceableCollection {
  @inlinable
  public init() {
    _storage = _Storage()
  }

  @inlinable
  public mutating func reserveCapacity(_ minimumCapacity: Int) {
    _storage.ensureUnique(minimumCapacity: minimumCapacity, linearGrowth: true)
  }

  @inlinable
  public mutating func replaceSubrange(
    _ subrange: Range,
    with newElements: __owned C
  ) where C.Element == Element {
    precondition(subrange.lowerBound >= 0 && subrange.upperBound <= count, "Index range out of bounds")
    let removalCount = subrange.count
    let insertionCount = newElements.count
    let deltaCount = insertionCount - removalCount
    _storage.ensureUnique(minimumCapacity: count + deltaCount)

    let replacementCount = Swift.min(removalCount, insertionCount)
    let targetCut = subrange.lowerBound + replacementCount
    let sourceCut = newElements.index(newElements.startIndex, offsetBy: replacementCount)

    _storage.update { target in
      target.uncheckedReplaceInPlace(
        inOffsets: subrange.lowerBound ..< targetCut,
        with: newElements[.. 0 {
        target.uncheckedInsert(
          contentsOf: newElements[sourceCut...],
          count: deltaCount,
          atOffset: targetCut)
      }
    }
  }

  @inlinable
  public init(repeating repeatedValue: Element, count: Int) {
    precondition(count >= 0)
    self.init(minimumCapacity: count)
    _storage.update { handle in
      assert(handle.startSlot == .zero)
      if count > 0 {
        handle.ptr(at: .zero).initialize(repeating: repeatedValue, count: count)
      }
      handle.count = count
    }
  }

  @inlinable
  public init(_ elements: S) where S.Element == Element {
    self.init()
    self.append(contentsOf: elements)
  }

  @inlinable
  public init(_ elements: C) where C.Element == Element {
    let c = elements.count
    guard c > 0 else { _storage = _Storage(); return }
    self._storage = _Storage(minimumCapacity: c)
    _storage.update { handle in
      assert(handle.startSlot == .zero)
      let target = handle.mutableBuffer(for: .zero ..< _Slot(at: c))
      let done: Void? = elements._withContiguousStorageIfAvailable_SR14663 { source in
        target.initializeAll(fromContentsOf: source)
      }
      if done == nil {
        target.initializeAll(fromContentsOf: elements)
      }
      handle.count = c
    }
  }

  @inlinable
  public mutating func append(_ newElement: Element) {
    _storage.ensureUnique(minimumCapacity: count + 1)
    _storage.update {
      $0.uncheckedAppend(newElement)
    }
  }

  @inlinable
  public mutating func append(contentsOf newElements: S) where S.Element == Element {
    let done: Void? = newElements._withContiguousStorageIfAvailable_SR14663 { source in
      _storage.ensureUnique(minimumCapacity: count + source.count)
      _storage.update { $0.uncheckedAppend(contentsOf: source) }
    }
    if done != nil {
      return
    }

    let underestimatedCount = newElements.underestimatedCount
    _storage.ensureUnique(minimumCapacity: count + underestimatedCount)
    var it: S.Iterator = _storage.update { target in
      let gaps = target.availableSegments()
      let (it, copied) = gaps.initialize(fromSequencePrefix: newElements)
      target.count += copied
      return it
    }
    while let next = it.next() {
      _storage.ensureUnique(minimumCapacity: count + 1)
      _storage.update { target in
        target.uncheckedAppend(next)
        let gaps = target.availableSegments()
        target.count += gaps.initialize(fromPrefixOf: &it)
      }
    }
  }

  @inlinable
  public mutating func append(contentsOf newElements: C) where C.Element == Element {
    let done: Void? = newElements._withContiguousStorageIfAvailable_SR14663 { source in
      _storage.ensureUnique(minimumCapacity: count + source.count)
      _storage.update { $0.uncheckedAppend(contentsOf: source) }
    }
    guard done == nil else { return }

    let c = newElements.count
    guard c > 0 else { return }
    _storage.ensureUnique(minimumCapacity: count + c)
    _storage.update { target in
      let gaps = target.availableSegments().prefix(c)
      gaps.initialize(from: newElements)
      target.count += c
    }
  }

  @inlinable
  public mutating func insert(_ newElement: Element, at index: Int) {
    precondition(index >= 0 && index <= count,
                 "Can't insert element at invalid index")
    _storage.ensureUnique(minimumCapacity: count + 1)
    _storage.update { target in
      if index == 0 {
        target.uncheckedPrepend(newElement)
        return
      }
      if index == count {
        target.uncheckedAppend(newElement)
        return
      }
      let gap = target.openGap(ofSize: 1, atOffset: index)
      assert(gap.first.count == 1)
      gap.first.baseAddress!.initialize(to: newElement)
    }
  }

  @inlinable
  public mutating func insert(
    contentsOf newElements: __owned C, at index: Int
  ) where C.Element == Element {
    precondition(index >= 0 && index <= count,
                 "Can't insert elements at an invalid index")
    let newCount = newElements.count
    _storage.ensureUnique(minimumCapacity: count + newCount)
    _storage.update { target in
      target.uncheckedInsert(contentsOf: newElements, count: newCount, atOffset: index)
    }
  }

  @inlinable
  @discardableResult
  public mutating func remove(at index: Int) -> Element {
    precondition(index >= 0 && index < self.count, "Index out of bounds")
    _storage.ensureUnique()
    return _storage.update { target in
      let result = self[index]
      target.uncheckedRemove(offsets: index ..< index + 1)
      return result
    }
  }

  @inlinable
  public mutating func removeSubrange(_ bounds: Range) {
    precondition(bounds.lowerBound >= 0 && bounds.upperBound <= self.count,
                 "Index range out of bounds")
    _storage.ensureUnique()
    _storage.update { $0.uncheckedRemove(offsets: bounds) }
  }

  @inlinable
  public mutating func _customRemoveLast() -> Element? {
    precondition(!isEmpty, "Cannot remove last element of an empty Deque")
    _storage.ensureUnique()
    return _storage.update { $0.uncheckedRemoveLast() }
  }

  @inlinable
  public mutating func _customRemoveLast(_ n: Int) -> Bool {
    precondition(n >= 0, "Can't remove a negative number of elements")
    precondition(n <= count, "Can't remove more elements than there are in the Collection")
    _storage.ensureUnique()
    _storage.update { $0.uncheckedRemoveLast(n) }
    return true
  }

  @inlinable
  @discardableResult
  public mutating func removeFirst() -> Element {
    precondition(!isEmpty, "Cannot remove first element of an empty Deque")
    _storage.ensureUnique()
    return _storage.update { $0.uncheckedRemoveFirst() }
  }

  @inlinable
  public mutating func removeFirst(_ n: Int) {
    precondition(n >= 0, "Can't remove a negative number of elements")
    precondition(n <= count, "Can't remove more elements than there are in the Collection")
    _storage.ensureUnique()
    return _storage.update { $0.uncheckedRemoveFirst(n) }
  }

  @inlinable
  public mutating func removeAll(keepingCapacity keepCapacity: Bool = false) {
    if keepCapacity {
      _storage.ensureUnique()
      _storage.update { $0.uncheckedRemoveAll() }
    } else {
      self = Deque()
    }
  }
}

extension Deque: Equatable where Element: Equatable {
  @inlinable
  public static func ==(left: Self, right: Self) -> Bool {
    return left.elementsEqual(right)
  }
}

#if swift(>=5.5)
extension Deque: @unchecked Sendable where Element: Sendable {}
#endif

extension Deque: ExpressibleByArrayLiteral {
  @inlinable
  @inline(__always)
  public init(arrayLiteral elements: Element...) {
    self.init(elements)
  }
}

extension Deque: CustomStringConvertible {
  public var description: String {
    _arrayDescription(for: self)
  }
}

extension Deque: CustomDebugStringConvertible {
  public var debugDescription: String {
    _arrayDescription(
      for: self, debug: true, typeName: "Deque<\(Element.self)>")
  }
}

@inlinable
public func _arrayDescription(
  for elements: C,
  debug: Bool = false,
  typeName: String? = nil
) -> String {
  var result = ""
  if let typeName = typeName {
    result += "\(typeName)("
  }
  result += "["
  var first = true
  for item in elements {
    if first {
      first = false
    } else {
      result += ", "
    }
    if debug {
      debugPrint(item, terminator: "", to: &result)
    } else {
      print(item, terminator: "", to: &result)
    }
  }
  result += "]"
  if typeName != nil { result += ")" }
  return result
}

extension Deque: CustomReflectable {
  public var customMirror: Mirror {
    Mirror(self, unlabeledChildren: self, displayStyle: .collection)
  }
}

extension Deque {
  @inlinable
  public init(
    unsafeUninitializedCapacity capacity: Int,
    initializingWith initializer:
      (inout UnsafeMutableBufferPointer, inout Int) throws -> Void
  ) rethrows {
    self._storage = .init(minimumCapacity: capacity)
    try _storage.update { handle in
      handle.startSlot = .zero
      var count = 0
      var buffer = handle.mutableBuffer(for: .zero ..< _Slot(at: capacity))
      defer {
        precondition(count <= capacity,
          "Initialized count set to greater than specified capacity")
        let b = handle.mutableBuffer(for: .zero ..< _Slot(at: capacity))
        precondition(buffer.baseAddress == b.baseAddress && buffer.count == b.count,
          "Initializer relocated Deque storage")
        handle.count = count
      }
      try initializer(&buffer, &count)
    }
  }
}

extension Deque {
  @inlinable
  public mutating func popFirst() -> Element? {
    guard count > 0 else { return nil }
    _storage.ensureUnique()
    return _storage.update {
      $0.uncheckedRemoveFirst()
    }
  }

  @inlinable
  public mutating func prepend(_ newElement: Element) {
    _storage.ensureUnique(minimumCapacity: count + 1)
    return _storage.update {
      $0.uncheckedPrepend(newElement)
    }
  }

  @inlinable
  public mutating func prepend(contentsOf newElements: C) where C.Element == Element {
    let done: Void? = newElements._withContiguousStorageIfAvailable_SR14663 { source in
      _storage.ensureUnique(minimumCapacity: count + source.count)
      _storage.update { $0.uncheckedPrepend(contentsOf: source) }
    }
    guard done == nil else { return }

    let c = newElements.count
    guard c > 0 else { return }
    _storage.ensureUnique(minimumCapacity: count + c)
    _storage.update { target in
      let gaps = target.availableSegments().suffix(c)
      gaps.initialize(from: newElements)
      target.count += c
      target.startSlot = target.slot(target.startSlot, offsetBy: -c)
    }
  }

  @inlinable
  public mutating func prepend(contentsOf newElements: S) where S.Element == Element {
    let done: Void? = newElements._withContiguousStorageIfAvailable_SR14663 { source in
      _storage.ensureUnique(minimumCapacity: count + source.count)
      _storage.update { $0.uncheckedPrepend(contentsOf: source) }
    }
    guard done == nil else { return }

    let originalCount = self.count
    self.append(contentsOf: newElements)
    let newCount = self.count
    let c = newCount - originalCount
    _storage.update { target in
      target.startSlot = target.slot(forOffset: originalCount)
      target.count = target.capacity
      target.closeGap(offsets: c ..< c + (target.capacity - newCount))
      assert(target.count == newCount)
    }
  }
}

https://github.com/apple/swift-collections/blob/main/Sources/DequeModule/Deque.swift

Leave a Reply