Skip to content

Commit d9b3886

Browse files
Custom Delta.SubSequence; Delta.Index: Stridable
1 parent c8efbca commit d9b3886

File tree

2 files changed

+259
-94
lines changed

2 files changed

+259
-94
lines changed

Sources/LightTableDelta/Delta.swift

Lines changed: 210 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -445,56 +445,13 @@ extension Delta: Sendable where Element: Sendable {}
445445

446446
extension Delta: BitwiseCopyable where Element: BitwiseCopyable {}
447447

448-
public struct _DeltaIterator<T>: IteratorProtocol {
449-
@usableFromInline
450-
let delta: Delta<T>
451-
@usableFromInline
452-
var index: Delta<T>.Index
453-
454-
@inlinable
455-
init(delta: Delta<T>, index: Delta<T>.Index) {
456-
self.delta = delta
457-
self.index = index
458-
}
459-
460-
@inlinable
461-
public mutating func next() -> T? {
462-
switch self.index.step {
463-
case .source:
464-
switch self.delta {
465-
case .source(let source):
466-
self.index = Delta<T>.Index(step: .sentinel)
467-
return source
468-
case .target(_):
469-
preconditionFailure("source index used with target delta")
470-
case .transition(source: let source, target: _):
471-
self.index = Delta<T>.Index(step: .target)
472-
return source
473-
}
474-
case .target:
475-
switch self.delta {
476-
case .source(_):
477-
preconditionFailure("target index used with source delta")
478-
case .target(let target):
479-
self.index = Delta<T>.Index(step: .sentinel)
480-
return target
481-
case .transition(source: _, target: let target):
482-
self.index = Delta<T>.Index(step: .sentinel)
483-
return target
484-
}
485-
case .sentinel:
486-
return nil
487-
}
488-
}
489-
}
490-
491448
extension Delta: RandomAccessCollection {
492-
public struct Index: Comparable {
449+
public struct Index: Hashable, Sendable, BitwiseCopyable {
493450
@usableFromInline
494-
enum Step: Comparable {
495-
case source
496-
case target
497-
case sentinel
451+
enum Step: Int8, Sendable, BitwiseCopyable {
452+
case source = 0
453+
case target = 1
454+
case sentinel = 2
498455
}
499456

500457
@usableFromInline
@@ -504,16 +461,18 @@ extension Delta: RandomAccessCollection {
504461
init(step: Step) {
505462
self.step = step
506463
}
507-
508-
@inlinable
509-
public static func < (lhs: Index, rhs: Index) -> Bool {
510-
lhs.step < rhs.step
511-
}
512464
}
513465

466+
public enum SubSequence {
467+
case empty(Delta<Element>.Index)
468+
case delta(Delta<Element>)
469+
}
470+
471+
public typealias Iterator = _DeltaIterator<Element>
472+
514473
@inlinable
515-
public func makeIterator() -> _DeltaIterator<Element> {
516-
_DeltaIterator(delta: self, index: self.startIndex)
474+
public func makeIterator() -> Iterator {
475+
Iterator(base: .delta(self), index: self.startIndex)
517476
}
518477

519478
/// The number of elements in the delta.
@@ -532,7 +491,7 @@ extension Delta: RandomAccessCollection {
532491
}
533492

534493
@inlinable
535-
public var startIndex: Delta.Index {
494+
public var startIndex: Index {
536495
switch self {
537496
case .source(_): Delta.Index(step: .source)
538497
case .target(_): Delta.Index(step: .target)
@@ -549,81 +508,238 @@ extension Delta: RandomAccessCollection {
549508
}
550509
}
551510

511+
@inlinable
512+
public func index(after i: Index) -> Index {
513+
i.advanced(by: 1)
514+
}
515+
516+
@inlinable
517+
public func index(before i: Index) -> Index {
518+
i.advanced(by: -1)
519+
}
520+
521+
/// The source element, if available; otherwise, the target element.
522+
@inlinable
523+
public var first: Element {
524+
self.resolve(favoring: .source)
525+
}
526+
527+
/// The target element, if available; otherwise, the source element.
528+
@inlinable
529+
public var last: Element {
530+
self.resolve(favoring: .target)
531+
}
532+
552533
@inlinable
553534
public subscript(position: Index) -> Element {
554535
switch self {
555536
case .source(let source):
556537
guard position.step == .source else {
557-
preconditionFailure("invalid index")
538+
preconditionFailure("index out of bounds")
558539
}
559540
return source
560541
case .target(let target):
561542
guard position.step == .target else {
562-
preconditionFailure("invalid index")
543+
preconditionFailure("index out of bounds")
563544
}
564545
return target
565546
case .transition(let source, let target):
566547
switch position.step {
567548
case .source: return source
568549
case .target: return target
569-
case .sentinel: preconditionFailure("invalid index")
550+
case .sentinel: preconditionFailure("index out of bounds")
570551
}
571552
}
572553
}
573554

574555
@inlinable
575-
public func index(after i: Index) -> Index {
576-
switch self {
577-
case .source(_):
578-
guard i.step == .source else {
579-
preconditionFailure("invalid index")
556+
public subscript(bounds: Range<Index>) -> SubSequence {
557+
guard bounds.lowerBound.step != bounds.upperBound.step else {
558+
return .empty(bounds.lowerBound)
559+
}
560+
switch (bounds.lowerBound.step, bounds.upperBound.step) {
561+
case (.source, .target):
562+
guard let source = self.source else {
563+
preconditionFailure("range out of bounds")
580564
}
581-
return Index(step: .target)
582-
case .target(_):
583-
guard i.step == .target else {
584-
preconditionFailure("invalid index")
565+
return .delta(.source(source))
566+
case (.target, .sentinel):
567+
guard let target = self.target else {
568+
preconditionFailure("range out of bounds")
585569
}
586-
return Index(step: .sentinel)
587-
case .transition(source: _, target: _):
588-
switch i.step {
589-
case .source: return Index(step: .target)
590-
case .target: return Index(step: .sentinel)
591-
case .sentinel: preconditionFailure("invalid index")
570+
return .delta(.target(target))
571+
case (.source, .sentinel):
572+
guard case .transition(source: let source, target: let target) = self else {
573+
preconditionFailure("range out of bounds")
592574
}
575+
return .delta(.transition(source: source, target: target))
576+
default:
577+
preconditionFailure("invalid range")
593578
}
594579
}
595580

596581
@inlinable
597-
public func index(before i: Index) -> Index {
582+
public subscript(unbounded: UnboundedRange) -> SubSequence {
583+
self[self.startIndex ..< self.endIndex]
584+
}
585+
}
586+
587+
extension Delta.Index: Comparable {
588+
@inlinable
589+
public static func < (lhs: Self, rhs: Self) -> Bool {
590+
lhs.step.rawValue < rhs.step.rawValue
591+
}
592+
}
593+
594+
extension Delta.Index: Strideable {
595+
public typealias Stride = Int
596+
597+
@inlinable
598+
public func distance(to other: Delta<Element>.Index) -> Stride {
599+
Int(self.step.rawValue - other.step.rawValue)
600+
}
601+
602+
@inlinable
603+
public func advanced(by n: Stride) -> Delta<Element>.Index {
604+
Self(step: Step(rawValue: self.step.rawValue + Int8(n))!)
605+
}
606+
}
607+
608+
extension Delta.SubSequence: RandomAccessCollection {
609+
public typealias Index = Delta<Element>.Index
610+
611+
public typealias SubSequence = Self
612+
613+
public typealias Iterator = Delta<Element>.Iterator
614+
615+
@inlinable
616+
public func makeIterator() -> Iterator {
617+
Iterator(base: self, index: self.startIndex)
618+
}
619+
620+
@inlinable
621+
public var count: Int {
598622
switch self {
599-
case .source(_):
600-
guard i.step == .target else {
601-
preconditionFailure("invalid index")
623+
case .empty(_): 0
624+
case .delta(let delta): delta.count
625+
}
626+
}
627+
628+
@inlinable
629+
public var underestimatedCount: Int {
630+
self.count
631+
}
632+
633+
@inlinable
634+
public var startIndex: Index {
635+
switch self {
636+
case .empty(let index):
637+
index
638+
case .delta(let delta):
639+
switch delta {
640+
case .source(_): Delta.Index(step: .source)
641+
case .target(_): Delta.Index(step: .target)
642+
case .transition(source: _, target: _): Delta.Index(step: .source)
602643
}
603-
return Index(step: .source)
604-
case .target(_):
605-
guard i.step == .sentinel else {
606-
preconditionFailure("invalid index")
644+
}
645+
}
646+
647+
@inlinable
648+
public var endIndex: Index {
649+
switch self {
650+
case .empty(let index):
651+
index
652+
case .delta(let delta):
653+
switch delta {
654+
case .source(_): Delta.Index(step: .target)
655+
case .target(_): Delta.Index(step: .sentinel)
656+
case .transition(source: _, target: _): Delta.Index(step: .sentinel)
607657
}
608-
return Index(step: .target)
609-
case .transition(source: _, target: _):
610-
switch i.step {
611-
case .source: preconditionFailure("invalid index")
612-
case .target: return Index(step: .source)
613-
case .sentinel: return Index(step: .target)
658+
}
659+
}
660+
661+
@inlinable
662+
public func index(after i: Index) -> Index {
663+
i.advanced(by: 1)
664+
}
665+
666+
@inlinable
667+
public func index(before i: Index) -> Index {
668+
i.advanced(by: -1)
669+
}
670+
671+
@inlinable
672+
public subscript(position: Index) -> Element {
673+
guard case .delta(let delta) = self else {
674+
preconditionFailure("index out of bounds")
675+
}
676+
return delta[position]
677+
}
678+
679+
@inlinable
680+
public subscript(bounds: Range<Index>) -> SubSequence {
681+
switch self {
682+
case .empty(let index):
683+
guard index == bounds.lowerBound && index == bounds.upperBound else {
684+
preconditionFailure("range out of bounds")
614685
}
686+
return self
687+
case .delta(let delta):
688+
return delta[bounds]
615689
}
616690
}
617691

618-
/// The source element, if available; otherwise, the target element.
619692
@inlinable
620-
public var first: Element {
621-
self.resolve(favoring: .source)
693+
public subscript(unbounded: UnboundedRange) -> SubSequence {
694+
self[self.startIndex ..< self.endIndex]
622695
}
696+
}
697+
698+
public struct _DeltaIterator<Element>: IteratorProtocol {
699+
@usableFromInline
700+
let base: Delta<Element>.SubSequence
701+
@usableFromInline
702+
var index: Delta<Element>.Index
623703

624-
/// The target element, if available; otherwise, the source element.
625704
@inlinable
626-
public var last: Element {
627-
self.resolve(favoring: .target)
705+
init(base: Delta<Element>.SubSequence, index: Delta<Element>.Index) {
706+
self.base = base
707+
self.index = index
708+
}
709+
710+
@inlinable
711+
public mutating func next() -> Element? {
712+
switch self.index.step {
713+
case .source:
714+
guard case .delta(let delta) = self.base else {
715+
return nil
716+
}
717+
switch delta {
718+
case .source(let source):
719+
self.index = Delta.Index(step: .sentinel)
720+
return source
721+
case .target(_):
722+
preconditionFailure("source index used with target delta")
723+
case .transition(source: let source, target: _):
724+
self.index = Delta.Index(step: .target)
725+
return source
726+
}
727+
case .target:
728+
guard case .delta(let delta) = self.base else {
729+
return nil
730+
}
731+
switch delta {
732+
case .source(_):
733+
preconditionFailure("target index used with source delta")
734+
case .target(let target):
735+
self.index = Delta.Index(step: .sentinel)
736+
return target
737+
case .transition(source: _, target: let target):
738+
self.index = Delta.Index(step: .sentinel)
739+
return target
740+
}
741+
case .sentinel:
742+
return nil
743+
}
628744
}
629745
}

0 commit comments

Comments
 (0)