forked from vapor/postgres-nio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMax2Sequence.swift
104 lines (91 loc) · 2.67 KB
/
Max2Sequence.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// A `Sequence` that can contain at most two elements. However it does not heap allocate.
@usableFromInline
struct Max2Sequence<Element>: Sequence {
@usableFromInline
private(set) var first: Element?
@usableFromInline
private(set) var second: Element?
@inlinable
var count: Int {
if self.first == nil { return 0 }
if self.second == nil { return 1 }
return 2
}
@inlinable
var isEmpty: Bool {
self.first == nil
}
@inlinable
init(_ first: Element?, _ second: Element? = nil) {
if let first = first {
self.first = first
self.second = second
} else {
self.first = second
self.second = nil
}
}
@inlinable
init() {
self.first = nil
self.second = nil
}
@inlinable
func makeIterator() -> Iterator {
Iterator(first: self.first, second: self.second)
}
@usableFromInline
struct Iterator: IteratorProtocol {
@usableFromInline
let first: Element?
@usableFromInline
let second: Element?
@usableFromInline
private(set) var index: UInt8 = 0
@inlinable
init(first: Element?, second: Element?) {
self.first = first
self.second = second
self.index = 0
}
@inlinable
mutating func next() -> Element? {
switch self.index {
case 0:
self.index += 1
return self.first
case 1:
self.index += 1
return self.second
default:
return nil
}
}
}
@inlinable
mutating func append(_ element: Element) {
precondition(self.second == nil)
if self.first == nil {
self.first = element
} else if self.second == nil {
self.second = element
} else {
fatalError("Max2Sequence can only hold two Elements.")
}
}
@inlinable
func map<NewElement>(_ transform: (Element) throws -> (NewElement)) rethrows -> Max2Sequence<NewElement> {
try Max2Sequence<NewElement>(self.first.flatMap(transform), self.second.flatMap(transform))
}
}
extension Max2Sequence: ExpressibleByArrayLiteral {
@inlinable
init(arrayLiteral elements: Element...) {
precondition(elements.count <= 2)
var iterator = elements.makeIterator()
self.init(iterator.next(), iterator.next())
}
}
extension Max2Sequence: Equatable where Element: Equatable {}
extension Max2Sequence: Hashable where Element: Hashable {}
extension Max2Sequence: Sendable where Element: Sendable {}